Имя: Пароль:
IT
Веб-мастеринг
Java. Удалить в ArrayList массив строк.
0 yavasya
 
23.03.20
12:18
Допустим мне в ArrayList нужно удалить 1,3,5 строку. В 1С для этого создается массив строк для удаления, и далее в метод удалить куда передается массив строк. Как сделать такую операцию в джава  чтобы индексы не сбивались ? Или остается строка с ссылкой null ?
1 mikecool
 
23.03.20
12:33
я не спец, но разве индексы останутся с пропусками после удаления?
2 fisher
 
23.03.20
12:35
(0) > "и далее в метод удалить куда передается массив строк"
Это где в 1С такое?
3 mikecool
 
23.03.20
12:36
(2) это он с ТЗ попутал
4 fisher
 
23.03.20
12:37
ArrayList - это просто динамический массив (работающий на классическом массиве). Какие нафиг "строки"?
(3) И где такое в ТЗ? У меня устаревший СП, что ли?
5 dezss
 
23.03.20
12:39
Ну так иди с конца массива, а не с начала.
6 mikecool
 
23.03.20
12:39
(4) а это уже я загнался ))
7 Кирпич
 
23.03.20
12:40
(0) Ну почитай help по ArrayList. Я вот почитал и вычитал, что можно удалять список объектов. Если у тебя в списке нет одинаковых объектов, то попробуй public boolean removeAll(Collection<?> c)
Если не устраивает, то используй HashMap какой нибудь или удаляй ручками с конца.
8 Кирпич
 
23.03.20
12:42
+(7) да и вычислить индекс следующего удаляемого элемента ума много не надо
9 fisher
 
23.03.20
12:43
Я в джава не настоящий сварщик, но если тебе надо выборочно удалять элементы массива, то ArrayList плохой выбор. Он же там кажись при удалении элемента все остальные сдвигает. Физически. И ессно индексы сбиваются. Если по индексам, то как 1С надо - с конца.
10 dezss
 
23.03.20
12:46
(7) removeAll удаляет все объекты, которые передашь, вроде. Не по индексам.
11 fisher
 
23.03.20
12:56
(0) Ты же можешь удалять не по индексу, а по ссылке (как в ТЗ). Но если нужно много строк удалять, то дешевле запустить полный перебор и удалять в процессе (кажись итератор там поддерживает удаление).
Но нужно держать в уме, что удаление из ArrayList - относительно дорогая операция на больших массивах. Для тяжелых алгоритмов нужны альтернативные подходы или другие структуры данных.
12 fisher
 
23.03.20
12:56
Тьфу, не строк - элементов.
13 yavasya
 
23.03.20
12:59
(11) очень интересно
14 yavasya
 
23.03.20
13:05
(4) ArrayList это таблица значений где каждая строка это многомерный массив
15 Garikk
 
23.03.20
13:07
(14) что там каждая строка? там каждая строка это ссылка на объект
16 yavasya
 
23.03.20
13:11
(15) а массив не ссылка?
17 fisher
 
23.03.20
13:11
(13) Три классические структуры данных:
ArrayList - динамический массив на непрерывных кусках памяти. Мгновенный доступ по индексу. Дорого удалять. Неравномерная стоимость добавления (когда кончается место - выделяется новый кусок побольше и в него копируется старый).
LinkedList - динамический массив на двусвязанном списке. Дорого доступаться по индексу, зато мгновенное удаление и добавление. Жрет больше памяти.
HashMap - мгновенный доступ по ключу. Нет доступа по индексу. Удаление через зануление. Проблемы с добавлением примерно такие же как у ArrayList.
(14) Нет. Это просто одномерный массив. Но если засунешь в качестве элементов другие ArrayList, то будет некий аналог таблицы значений.
18 ИУБиПовиц
 
23.03.20
13:12
А через iterator(). hasNext ().remove если попробовать? индексы тоже перестраиваются?
19 fisher
 
23.03.20
13:14
(18) Конечно перестраиваются. Удаление через итератор (если поддерживается) гарантирует просто что перебор по итератору при удалении не собъется.
20 yavasya
 
23.03.20
13:14
(18) да там два пути, итератор перестраивать на +2 после удаления , и с конца перебирать. хотел по ссылке, но это невозможно
21 yavasya
 
23.03.20
13:16
(19) а что останется после удаления ? удалили строку, итератор не сбился, что осталось?
22 fisher
 
23.03.20
13:20
(21) Останется ГДЕ? В массиве ничего не останется. Если получил ссылку на объект по итератору, то она никуда не денется. Ты же просто удалил элемент массива, а не объект ссылка на который там лежала.
23 yavasya
 
23.03.20
13:24
(21) ну смотри , массив 0,1,2,3,4

удалил 2 и 4 элемент , остается 0,2,4. при переборе массива какая конструкция идет 0, null, 2,null,4 ? как индексы сохранить ?
24 fisher
 
23.03.20
13:29
(23) В жаве в ArrayList ты не можешь засунуть int (примитивный тип). Только объекты Integer (ссылочный тип-обертка). Т.е. ArrayList будет содержать ссылки на объекты Integer.
Если удалишь сначала 4 элемент по индексу а затем второй, то в массиве останется 0,2,4 и тоже самое будет выдавать при переборе.
Но если при переборе ты в какой-то переменной сохранял ссылки на 1 и 3, то они останутся доступны (объекты живут, пока на них есть ссылки, как и в 1С).
Если хочешь чтобы индексы остались и были null, тогда тебе не удалять надо а просто присваивать нужным элементам null явно. Получишь разряженный массив.
25 Salimbek
 
23.03.20
13:31
(23) Какие "индексы" сохранить и куда? У вас где-то в других местах хранятся эти самые "индексы"? Если да, то ответ очевиден, вам ничего удалять нельзя. Можно, например, ставить своеобразную "пометку удаления".
26 yavasya
 
23.03.20
13:38
(25) я имел ввиду что если индексы не сбиваются, значит ссылки на строки остаются
27 yavasya
 
23.03.20
13:39
(24) Если удалишь сначала 4 элемент по индексу а затем второй, то в массиве останется 0,2,4 и тоже самое будет выдавать при переборе. а как ты оставишь тож самое при переборе ? remove в конце  перебора вызвать?
28 Garykom
 
гуру
23.03.20
13:41
(0) Никогда не удаляй строки - всегда создавай новый "список" и переноси туда только нужные строки, которые "надо оставить".
29 Salimbek
 
23.03.20
13:41
(26) Еще раз, вы упорно делаете акцент на "индексы", я и спрашиваю - для чего вам это?
30 Salimbek
 
23.03.20
13:42
(28) Это может быть довольно дорогой операцией.
31 yavasya
 
23.03.20
13:42
(29) если индексы собьются при удалении, то нельзя по ним получать строки
32 Garykom
 
гуру
23.03.20
13:44
(30) Это удаление строки в цикле дорогая операция, когда на каждом шаге цикла новый объект пересоздается платформой и туда строки переносятся.
33 Salimbek
 
23.03.20
13:45
(31) Если вы строку удалили, то какую строку по этому удаленному индексу вы хотите получить?
34 Garikk
 
23.03.20
13:45
(32) если в массиве 20гб данных, пересоздавать массив будет пипец как дорого, проще реально строки циклом удалять
35 Salimbek
 
23.03.20
13:47
(34) Согласен, только еще эффективнее использовать динамически связанные структуры. Т.к. при простом удалении как раз и будет каждый раз пересоздаваться "массив 20гб данных"
36 yavasya
 
23.03.20
13:48
(33) у меня складывается впечатление вы читаете с конца, поэтому ничего не понятно
37 Кирпич
 
23.03.20
13:50
(0)Так надо?
На Java первый раз в жизни пишу :)

import java.util.ArrayList;
import java.util.Arrays;

public class Main
{
    public static void removeAll(ArrayList<String> z, int[] ii) {
        
        Arrays.sort(ii);
        int xx = 0;
        for (int x = 0; x < ii.length; x++ ) {
            z.remove(ii[x]-xx);
            xx++;
        }
        
    }
    public static void main(String[] args) {
        
        ArrayList<String> x = new ArrayList<String>();
        x.add("000");
        x.add("100");        
        x.add("200");
        x.add("300");    
        x.add("400");        
        x.add("500");
        x.add("600");        
        System.out.println(x);
        removeAll(x,new int[]{5,3,1});
        System.out.println(x);
        
    }
}
38 yavasya
 
23.03.20
13:51
(37) я тоже так могу копировать код с форумов. ищу оптимальное решение
39 Кирпич
 
23.03.20
13:52
(38) я не копировал. я сам.
40 yavasya
 
23.03.20
13:54
(39) ты ж в первый раз в жизни видишь
41 fisher
 
23.03.20
13:56
(36) Я читаю с начала и тоже нифига не понимаю.
42 Кирпич
 
23.03.20
13:57
(40) ПИШУ, а не ВИЖУ
43 Salimbek
 
23.03.20
13:57
(36) Я читаю тему с самого начала, и если вам непонятен мой вопрос, то:
1) "В 1С для этого создается массив строк для удаления, и далее в метод удалить куда передается массив строк." - где вы такое нашли? А если этого нету, то для чего выдумывать несуществующие сущности?
2) "Как сделать такую операцию в джава  чтобы индексы не сбивались ? " - Вот тут вот - для чего вам тут нужны некие "индексы", и чтобы они "не сбивались"?
3) "Или остается строка с ссылкой null ?" - если вы строку удалили, то null не будет.
44 Кирпич
 
23.03.20
14:06
(43) Мне кажется он хотел удалять из списка элементы не по одному, а несколько сразу.
Типа вот список {000,100,200,300,400,500,600} отсчет с нуля
удалить надо [1,3,5]
Получаем {000,200,400,600}
45 Кирпич
 
23.03.20
14:07
(40) Так или не так?
46 yavasya
 
23.03.20
14:12
(45) все верно
47 yavasya
 
23.03.20
14:16
(43) 1) "В 1С для этого создается массив строк для удаления, и далее в метод удалить куда передается массив строк." - где вы такое нашли? А если этого нету, то для чего выдумывать несуществующие сущности? Вы тролите ? С таблицами значений не работали ?
2) "Как сделать такую операцию в джава  чтобы индексы не сбивались ? не прочитали ничего
3) "Или остается строка с ссылкой null ?" - если вы строку удалили, то null не будет. Это ваше сугоболичное не начем не основанное убеждение
48 Кирпич
 
23.03.20
14:16
(46) Ну вот тебе решение в (37)
Но лучше использовать HashMap вместо ArrayList
49 yavasya
 
23.03.20
14:18
(48) видимо так . или по значению строки удалять
50 Salimbek
 
23.03.20
14:19
(45) Тогда в вашем коде из (37) надо немного не так:
for (int x = 0; x < ii.length; x++ )
поменять на:
for (int x = ii.length-1; x >=0 ; x-- )
и всякие танцы с xx - убрать. Еще бы желательно сделать проверку на возможные дубли в ii, чтобы случайно за пределы массива не вывалиться.

(46) Самый эффективный вариант вам уже сказали - делать копию массива и туда переносить элементы из первого, за исключением тех, кто в вашем списке. При этом можно будет использовать команды копирования блоков данных, которые очень эффективно компилируются.
51 yavasya
 
23.03.20
14:22
(50) перебрать с конца уже было.
амый эффективный вариант вам уже сказали - делать копию массива и туда переносить элементы из первого, за исключением тех, кто в вашем списке. При этом можно будет использовать команды копирования блоков данных, которые очень эффективно компилируются. Здесь я с вами соглашусь.
52 fisher
 
23.03.20
14:24
Вообще лучше всего использовать removeIf и туда засунуть предикат условия на удаление.
Так хотя бы "схлопывание" массива будет выполнено за один присест.
53 Конструктор1С
 
23.03.20
14:26
(0) а как ты пришел к тому, что тебе нужно удалить конкретные индексы? Правильнее всё-таки удалять объекты. И если ты получил индексы, то где-то чуть раньше работал с объектами
54 Dionis Sergeevich
 
23.03.20
14:28
Это форум про аниме? Как пропатчить кде под фрибсд?))
55 yavasya
 
23.03.20
14:29
(53) если удалишь строку, то поплывут индексы. Про это.
56 Salimbek
 
23.03.20
14:30
(47) 1) "Вы тролите ? С таблицами значений не работали ?" - Вовсе нет, работал. Метода "Удалить" с передачей внутрь массива - ни разу не сталкивался. Ни у массива тут: https://helpme1c.ru/massivy-v-yazyke-1s-8-v-primerax ни у Таблицы значений тут: https://helpme1c.ru/tablica-znachenij-v-yazyke-1s-8-v-primerax Везде "Удалить(Индекс)"
3) Х.з. как там в Ява, но в С++ вообще нельзя удалить элемент массива, поэтому придумывают велосипеды, типа:
https://ru.stackoverflow.com/questions/168764/%d0%a3%d0%b4%d0%b0%d0%bb%d0%b5%d0%bd%d0%b8%d0%b5-%d1%8d%d0%bb%d0%b5%d0%bc%d0%b5%d0%bd%d1%82%d0%b0-%d0%bc%d0%b0%d1%81%d1%81%d0%b8%d0%b2%d0%b0-%d0%bf%d0%be-%d0%b8%d0%bd%d0%b4%d0%b5%d0%ba%d1%81%d1%83
"Судя по всему, много элементов удалять не придётся, а потому просто смещаете все элементы, кроме удаляемого, на 1 влево и уменьшаете длину массива на 1."

k - нужный индекс
for (long i = k; i < n-1; ++i)
{
  a[i] = a[i + 1];
}
--n;

Можно переделать этот алгоритм и на множество элементов.
57 fisher
 
23.03.20
14:32
(53) Насколько я понял, он хотел по аналогии с удалением строк таблицы значений по ссылкам сделать (в сабже он про это писал). Но запутался в своей эмуляции ТЗ на вложенных списках, не смог этого сделать и попытался через индексы. А то, что можно прямо в процедуру удаления передать ссылку на функцию с условием удаления он догадаться не смог, потому что в 1С таких вариантов нет.
58 yavasya
 
23.03.20
14:37
(57) блин, да это легко написать. я не знаю как правильно
59 yavasya
 
23.03.20
14:39
(56) ну да, это с конца способ перебрать
60 yavasya
 
23.03.20
14:42
(57) прямо в процедуру удаления передать ссылку на функцию с условием удаления. а это как ?
61 Salimbek
 
23.03.20
14:43
(59) Вы внимательно уловили суть этого алгоритма? Там нету ни удаления, ни перебора с конца.
62 yavasya
 
23.03.20
14:46
(61) сделать копию массива и туда переносить элементы из первого, за исключением тех, кто в вашем списке.
63 yavasya
 
23.03.20
14:46
(61) там нативная библиотека и она очень быстро работает
64 fisher
 
23.03.20
14:48
(60) См. (52)
65 Salimbek
 
23.03.20
14:49
(60) Это:
    public static void removeAll(ArrayList<String> z, int[] ii) {
        
        Arrays.sort(ii);
        z.removeIf(el -> (Arrays.binarySearch(ii, el) >= 0));
      
    }
66 yavasya
 
23.03.20
14:51
(65) ты ооп пишешь ? лямда выражение массивы, бинарные деревья
67 Salimbek
 
23.03.20
14:51
(62) ну почти, только копии массива не создается, а текущие элементы переписываются
68 Salimbek
 
23.03.20
14:52
(66) Ты у меня на счет кода (65) спрашиваешь или вообще?
69 yavasya
 
23.03.20
14:52
вообще
70 fisher
 
23.03.20
14:54
(65) Я подозреваю, что к списку индексов для удаления он пришел от безысходности. И в лямбде ему нужно просто свое условие прописать.
Но вариант красивый. Чувствуется практический опыт в java :)
71 fisher
 
23.03.20
14:59
(66) Arrays.binarySearch - это аналог Найти() в массиве 1С. А лямбды в java - это просто синтаксический сахар вокруг объектов. Просто чтобы писанины было меньше.
72 Salimbek
 
23.03.20
14:59
(69) Вообще пишу на том, на чем удобно

(70) "Чувствуется практический опыт в java :)" - у меня есть опыт с замыканиями в Ruby и немного C++, конструкцию removeIf - подсказал ты, быстрый поиск элемента в массиве нашел в гугле. И вуаля, я уже гуру в java :-)
73 yavasya
 
23.03.20
15:01
(72) ясно. только начал ооп изучать, даже ты пока гуру)
74 yavasya
 
23.03.20
15:03
(72)далеко не факт что правильно . тролишь ты профессионально)
75 fisher
 
23.03.20
15:04
(72) Ну дык. Иллюстрация к тому, что хорошему прогу пофиг на чем писать. И что, джавовую лямбду за минуту нарисовал исключительно из опыта замыканий в руби? Собака подозревака. Они в джава специфические.
76 Salimbek
 
23.03.20
15:05
(74) Если ты внимательно прочитаешь мои посты, то поймешь, что я никого не троллю.  Я серьезно пытался понять, нахрена тебе обязательное сохранение индексов.

Кстати - в (65) ошибка, не делай так :-((( Там ищется элемент массива, а тебе нужон именно индекс...
77 Salimbek
 
23.03.20
15:07
+(76) Особо отмечу, что условия "проход за один цикл" в операторе removeIf нет.
78 fisher
 
23.03.20
15:14
(76) По-моему, оно не скомпилируется. Arrays.binarySearch(ii, el) - туда ii само в тело предиката не прилетит как в функциональных языках.
79 fisher
 
23.03.20
15:20
А может и прилетит, если лямбды в сабклассы разворачиваются... Давно пытался в это погрузиться - забросил. Не помню уже, не слушайте меня :)
80 Salimbek
 
23.03.20
15:31
(78) Там проблема в другом, там в (ii, el) - el - это элемент массива z, т.е. строка. А нужен Индекс.

Вообще выгоднее в элементах этого самого ArrayList сделать еще одно поле, типа isDeleted boolean, которое потом проставить на удаляемых элементах в true или на нарисованной форме, или пробежавшись по массиву индексов. А уже затем

z.removeIf(el -> el.isDeleted)

ну или как оно там к полям коллекции обращается...
81 fisher
 
23.03.20
15:38
(80) Чем выгоднее? Почему в предикате не проверять все что надо? Разве что для повышения читабельности, если там совсем что-то хитровымученное.
82 Salimbek
 
23.03.20
15:44
(81) Выгоднее, например, тем, что isDeleted можно и в графической форме дать юзеру проставлять, да и вообще, isDeleted это как раз по 1С-ному ))) А так - согласен, чем меньше беготни по массиву, тем быстрее все работает.
83 Доктор Манхэттен
 
23.03.20
16:59
(0) Если в массиве важны индексы, то это явный признак того, что массив используете не по назначению. Индексы массива не должны нести никакой смысловой нагрузки. При правильно спроектированном коде, индексы не используются в принципе.
84 MadHead
 
23.03.20
18:32
Всю ветку не читал.
По классике правильнее всего удалить через итератор (понадобиться переменная которая определяет четный/не четный)
85 Доктор Манхэттен
 
23.03.20
22:06
(0) В чем вообще суть задачи? По какому условию нужно удалять элементы, и для чего впоследствии нужны индексы? Напиши полностью что ты хочешь сделать.
86 cViper
 
23.03.20
22:20
(0) Используй массив вместо листа.
87 cViper
 
23.03.20
22:30
(14) ArrayList - это реализация интерфейса List на базе массива.
А то что таблица значений, это либо HashMap либо просто ArrayList<ArrayList<String>> либо String[][],  смотря что тебе надо.
(37) Лучше бы не писал *)
(0) Положи в HashSet значения которые надо удалить. Итерирую массив значений проверяй if(set.contains(value)) то переписывай значение мссива на null.
88 cViper
 
23.03.20
22:35
(0) Еще, как вариант, если в твоем листе только положительные числа, то модешь им добавлять знак -. Тогда и ндексы сохранишь и значения предыдущие будут.
89 MadHead
 
23.03.20
22:39
Если я понял правильно то нужно удалить нечетные элементы

        List<Integer> list = Stream.of(1, 2, 3, 4, 5).collect(Collectors.toList());
        Iterator<Integer> iter = list.iterator();
        boolean isOdd = false;
        while (iter.hasNext()) {
            iter.next();
            if (isOdd) {
                iter.remove();
            }
            isOdd = !isOdd;
        }

        list.forEach(System.out::println);

Если стараться придерживаться более функционального стиля, то можно сделать без сайдэффектов преобразовать List элементов в Stream [index, value] и применить фильтр.
90 cViper
 
23.03.20
22:40
(71) не знаю как работает Найти в 1С, но binarySearch это стандартынй алгоритм бинарного поиска ,который работает только на отсортированных данных. Что касается стримов, то они еще и медленне работают чем простые циклы.
(65) Неоптимальное решение. Cортировка будет за O(n*log(n))(каждый бинарный поиск буде за O(log(n)), но им можно пренебречь). в (87) решение работает за O(n)
91 Сияющий в темноте
 
23.03.20
23:01
ArrayList это просто массив,если из егг середины удаляется элемент,то остальные просто сдвигаются
при удалении с конца будет немного меньше сдвигов.

просто,если порядок элементов не важен,то,обычно,в дыру после удаления пихают последний элемент-это очень быстро,но часто дает очень странный результат.
92 Сияющий в темноте
 
23.03.20
23:04
и еще у java нет возможности изменчть выделенный блок памяти,поэтому,ввделив 16 элементов и кдалив что-то мы получим пустые ссылки в конце,так как стстема для уиеньшения массива не будет его копировать.

и не забываем,что в тех языках,где есть перевыделение памяти,это очень критичная к производительности операция,так как требует выполнения копирования блокп данных.
93 Доктор Манхэттен
 
23.03.20
23:17
(89) >> Если я понял правильно то нужно удалить нечетные элементы

Очень сомневаюсь что задача стоит именно так. Представьте, приходит тетя Глаша из Бухгалтерии, и говорит: "Мне тут прислали имейл с ArrayList, нужно из него удалить все нечетные элементы".
94 MadHead
 
23.03.20
23:24
(93) Это довольно частый вопрос на собесах и синтетических задачах.
К примеру можно представить, что нужно получить часть данных или алгоритм игры требует такого удаления.
95 MadHead
 
23.03.20
23:25
(92) у ArrayList есть метод trimToSize
96 Доктор Манхэттен
 
23.03.20
23:39
(94) Пока ТС молчит, непонятно это действительно синтетическая задача, или он придумал неоптимальное решение для реальной задачи, и теперь пытается вставить в него костыли.
97 Доктор Манхэттен
 
23.03.20
23:55
(94) Если бы это был JS, я бы написал просто фильтр нечетных:

return [0, 1, 2, 3, 4].filter((_, i) => i & 1);

Думаю в Java наверняка есть аналог такой функции.
99 cViper
 
24.03.20
02:15
(92) При расширении или сужении массива никакого копирования не проиходит. Просто обьекты переносятся в массив нового размера. Эта процедура очень быстрая, выполняется нативный код System.arrayCopy. А старый обьект массива удалится сборщиком мусора.
100 Конструктор1С
 
24.03.20
03:42
(55) обычно индексы массива интересуют только сам массив. А если не только сам массив, то это кривой алгоритм
101 Конструктор1С
 
24.03.20
03:49
(96) это может быть академическая задача из курса по программированию или учебника какого. Академические задачки по программированию часто отличаются бессмысленностью и беспощадностью
102 Salimbek
 
24.03.20
09:09
У автора задача - Имеется ArrayList и в массиве индексы строк (х.з. как полученных), которые надо удалить из этого ArrayList.

Самый оптимальный вариант, по моему, в (56), т.к. выполняется не просто за O(n), а еще и это самое O - можно реализовать довольно эффективно.
А что касаемо (87), то у вас спрятаны дополнительные O(k*log(k)) во фразе "Положи в HashSet" и множитель O(log(k)) в "проверяй if(set.contains(value))" Итого сложность будет: O(k*log(k))+O(n*log(k))
103 Сияющий в темноте
 
24.03.20
10:06
(99) копирование массива-быстрая операция?
а если в массиве миллион элементов
вот после таких рассуждений пишется код,который на реальных данных уходит в down,и никто не понимает,что случилось.
104 yavasya
 
24.03.20
10:12
(103) да, потому что нативный метод, а jvm не умеет работать с памятью так же хорошо как c++ .
105 MadHead
 
24.03.20
10:39
(97) В JS массивы - это скоере ассоциативный(индекс->значение) массив чем классический, сравнение не очень корреткное. То есть в джаве нужно вручную создать пары индекс-значение после чего уже можно преобразовать коллекцию в stream и применить фильтр. Есть либы которые реализовую метод zipWithIndex.  
(99) При увеличении точно происходит копирование в новую область большего рамера и при уменьшении скорее всего тоже.
(103) Копирование массива операция относительно быстрая, соизмеримая с подобной операцией в C/C++ но сложность операции O(N). В принципе сложность описывает как зависит время выполнения от ко-ва элементов и не говорит ничего о реальном времени выполнения. Если размер коллекции сильно меняется, то есть более оптимальные структуры для хранения таких данных. В Скале на пример есть Vector который по сути явялется деревом с массивами в узлах размерностью 32элемента. Это позволяет совместить плюсы linkedlist и arraylist. Большой плюс, что такая коллекция оптимально использует кэш процессора при итерации, так как 32-х разрядные массивы помещаются в кэш линию
106 fisher
 
24.03.20
10:53
(103) Копирование с помощью System.arrayCopy - относительно быстрое даже на больших объемах. Насколько я понимаю, под капотом оно использует команды процессора блочного копирования памяти или что-то в этом духе. Встречал на просторах сравнение с обычным поэлементным копированием и копированием через этот метод - разница больше чем на порядок. Типа миллион элементов где-то 200 мс поэлементно у кого-то заняло, а этой хренью то ли за 10, то ли за 15 мс скопировало. Понятно, что голову все равно включать надо. Но все равно ArrayList остается самой универсальной реализацией динамического массива.
107 fisher
 
24.03.20
10:57
А удалять или занулять элементы - это тоже всегда компромисс и решается по месту. Если массив не слишком большой - лучше удалять. Тем более, что removeIf делает это оптимизированно. Обслуживать разряженный массив - тоже не фунт изюму и легко может в итоге привести к неожиданным сайд-эффектам.
108 sevod
 
24.03.20
11:04
Хочешь на Java-велосипед, колеса невообразимой формы? Зайди на 1С форум!
Вася, не удаляй из ArreyList ничего, ты еще не дорос до такого сверх высокого уровня. Ведь для этого нужно прочитать что такое ArreyList, а так же ознакомиться с другими коллекциями Java. Это ведь целый 8-ой уровень JavaRush (когда то до 10 было бесплатно, сейчас не знаю).
Вася, забудь слово ООП. Учи с начала. Возьми какой нибудь готовый курс и с нуля. Последовательно. Без пропусков.
Смещение индексов в ArreyList при добавлении/удалении элементов, это то, ради чего его и создавали. А ты с этим зачем то борешься. Для того что бы это понять, нужно сравнивать с Arrey. Но ведь для того, что бы это понять, придется почитать об этом. Методом тыка может не прокатить.
109 yavasya
 
24.03.20
11:07
(108) качественный троль
110 sevod
 
24.03.20
11:09
(109) это был лучший ответ в этой ветке. У меня чуть пукан не разорвало когда я это все читал. И я реально на 8 лвл javarush и там реально проходят коллекции.
Тебе реально рано с массивами работать, учи с нуля!
111 yavasya
 
24.03.20
11:10
(108) я кстати на курсе программирования, то что сделать можно и как сделать я знаю. основных вопрос 1. Как сделать правильно и оптимально
112 yavasya
 
24.03.20
11:11
(110) ну и на каком уровне там разбираются? удалил элемент и молодец? умничай для себя . не буду кормить тролей
113 sevod
 
24.03.20
11:12
(111) а чего ты тогда основ не знаешь? и главное, почему ты этот вопрос на своем курсе не задал?!
114 fisher
 
24.03.20
11:13
(105) Пошел почитать за класс Vector. Жутко было интересно, как же они перебалансируют дерево при удалениях/добавлениях. А оно иммьютбл. Ыыыыыы :)
115 antgrom
 
24.03.20
11:15
(110) 8 уровень javarush это невысокий уровень. Любой 1Сник пройдёт легко, без предварительных знаний java. Нужно только время - несколько дней.
116 sevod
 
24.03.20
11:19
(115) а я о чем? это околонулевой. Поэтому и пишу на полном серьезе что бы начал с нуля. Если прочитает что такое ArrayList и просто Array, то поймет какой он вопрос задал.
117 fisher
 
24.03.20
11:20
(105) Я теперь вообще не понимаю, нахрена там внутри дерево, если оно иммьютбл. Что это дает в сравнении с обычным иммьютбл-массивом? Где про это почитать можно?
118 sevod
 
24.03.20
11:24
(117) скорее всего для совместимости оставили. Что бы древний код не помер. Загугли по этому дереву, если попадешь на оф. документацию, возможно где то на странице будет рекомендованные на данный момент методы.
Там много таких. К примеру Date тоже лучше не использовать.
119 fisher
 
24.03.20
11:26
(118) Речь про Scala
120 fisher
 
24.03.20
11:30
(105) Могу только предположить, что это позволяет делать хитрые оптимизации при операциях над векторами. Чтобы не копировать неизменные блоки, уменьшая общее количество копирований.
121 MadHead
 
24.03.20
11:35
(117) Имьютабл в прицепе функциональный подход - это по максимум отказаться от мутабельных объектов. Но оверхед не такой большой, так как при копировании сами массивы не пересоздаются. И отсуствие сайд эффектов позволяет обрабатыват коллекции многопоточно без синхронизации.
К примеру есть коллекция содержащий 320 элементов - это 10 массивов по 32 элемента для vector или массив 320элементов.
1a. При добавлении элемента в vector скопируется 10 ссылок + выделиться дополнительный массив размером 32
1b. При добавлении элемента в массив будет выделена область памяти под все данныее нового размера, а старые будут удалены.
122 MadHead
 
24.03.20
11:39
(120) Массив даст все те же приемущества в плане векторных вычислений. Что бы быть на одной странице поясню, что я имею в виду под векторными вычислениями.
Современные процессоры подддерживают векторыне операции - то есть позволяют сделать 8 и более арифметических однотипных операция за одину операцию. Это дает существенный прирост в производительности CPU операций (активно используется в pandas и Apache arrow)
123 fisher
 
24.03.20
11:50
(121) Идея понятна. Прикольно. В среднем ArrayList будет быстрее. Зато тут иммьютбл со всеми своими плюшками и одинаковое время выполнения операций без внезапных просадок.
124 Конструктор1С
 
24.03.20
12:03
(104) "jvm не умеет работать с памятью так же хорошо как c++"

Ты сильно заблуждаешься. Так было лет 20 назад. Современная джавамашина сама умеет хитро оптимизировать код, к тому же позволяет произвести тонкую настройку. На плюсах можно написать более производительный код, но для этого требуется:
а) высокая квалификация плюсника
б) дофига времени
в 99% случаев овчинка выделки не стоит
125 MadHead
 
24.03.20
12:21
(123) Если брать среднюю температуру по больнице, то можно сказать что в среднем arraylist быстрее. Производительность вопрос многогранный. Каким-то задачам важна равномерность операций, что бы вставка занимала фиксированное время, а не генерировала периодические спайки при копировании всех элементов массива. Для каких-то задач важно оптимальнео использование памяти, в arraylist можно выделить сразу массив огромного размера, что бы не происходило перевыделение памяти, но если размер массива сложно предугадать, то память будет использоваться не оптимально. К примеру вставка начало arraylist более медленная операция чем ставка в начало linkedlist.
https://docs.scala-lang.org/overviews/collections/performance-characteristics.html

И имутабельность и неблокарующее распаралеливание позволят больше сфоркусироваться на алгоритме чем на реализации и по факту приложение в целом будет работать быстрее. Хороший пример - это модель акторов. Подход можно назвать имутабельным по этому паттерну построен самый быстрые вэб сервер.
126 MadHead
 
24.03.20
12:21
127 cViper
 
24.03.20
13:19
(102) Вы сравниваете 2 алгоритма решающих разные задачи. В (90) он удаляет несколько значений, а не единичное. А в (56) единичное значчение. Попробуйте и переделайте свое решение для нескольких значений. И да, вы не умеете считать сложность алгоритмов.
(103) А что медленного в работе System.arrayCopy()? Он ведь по сути только создает новый массив и закидывает туда старые обьекты из старого массива.
(114) В TreeMap в основе также лежит дерево, самобаланчируемое красно-черное. Это классическая структура данных описанная во многих книгах по CS.
(117) Оно упорядочивает (сортирует) исходные данные и дает гарантированную сложность доступа O(log(n))
128 Salimbek
 
24.03.20
13:20
(127) Ну держи... Смогешь быстрее?

    public static ArrayList<String> removeAll(ArrayList<String> z, int[] ii) {
        if(ii.length==0) return z;
        ArrayList<String> nz = new ArrayList<String>();
        Arrays.sort(ii);
        int prev=0;
        for (int x = 0; x < ii.length; x++ ) {
            if(ii[x]-prev>0)
                nz.addAll(z.subList(prev,ii[x]));
            prev=ii[x]+1;
        }
        if(prev<z.size()){
            nz.addAll(z.subList(prev,z.size()));
        }
        return nz;
    }
129 cViper
 
24.03.20
13:22
(124) Ну да, "just in time" компиляция опимизирует все по-максимуму. Некоторые методы также переводятся в нативный код. В jvm hotspot для этого сделано 2 компилятора: client and server.
server компилятор может опитимизировать до нативного кода, в зависимости от того, как часто используется java метод.
130 cViper
 
24.03.20
13:29
(128) Судя по всему я неправильно понял задачу. Думал у нас на входе коллекция со значениями которые надо удалить, а не с индексами. Код нечитаемый.
Если у нас на входе массив индексов и все значения в коллекции значений положительные, то вариант из (88) вполне рабочий и он будет быстрее чем (128).
131 fisher
 
24.03.20
13:47
(127) Не очень понял, к чему вы упомянули красно-черное дерево. Я, если что, в курсе как оно работает. Дерево, упомянутое для Vctor, ни разу на него не похоже. И именно поэтому я написал то, что написал.
132 yavasya
 
24.03.20
13:47
(130) ты правильно понял задачу, ее остальные не могут понять, не знают что таблицу значений можно в ArrayList представить. Как можно удалить массив строк как в 1С?
133 fisher
 
24.03.20
13:52
(131) Какая, в одно место, сортировка, если оно имутабельное? Не тупи, уже все дано разобрались зачем так сделано. Если бы ты больше читал, чем красовался знакомством с О-нотацией, то тоже бы разобрался.
134 cViper
 
24.03.20
13:52
(131) Увидел что вы заинтересовались классом Vector. Как работает этот класс в Scala не знаю. Увидел комментарий про дерево. Решил порекомендовать , раз есть интерес.
135 Salimbek
 
24.03.20
13:52
(132) Разъясните, пожалуйста, еще раз, для меня, как для особо тупого. У тебя в массиве _Значения_ (о чем пишет в (130)) или _Индексы_строк_ (как ты пишешь в (0))?
136 cViper
 
24.03.20
13:54
(133) Предполагаю, что этот комментарий ко мне адресован. Я не знаю как работае ткласс Vector в Scala. Но могу предположить, что у него в конструкторе есть список входящих значений, которые он и сортирует при построении дерева.
137 fisher
 
24.03.20
14:00
(136) Не надо предполагать. MadHead ранее уже все объяснил.
138 sevod
 
24.03.20
14:01
(132)"... что таблицу значений можно в ArrayList представить."
Нельзя этого сделать. Учи азы. В ArrayList  нет колонок. Это массив. Если нужна пара ключ - значение в java, Map используй.
139 Salimbek
 
24.03.20
14:03
(130) Вы вот серьезно в задаче "Имеется ArrayList и в массиве индексы строк (х.з. как полученных), которые надо удалить из этого ArrayList"
увидели "Имеется ArrayList положительных чисел и в массиве индексы строк (х.з. как полученных), надо добавлять знак '-' к числам в этих строках"?
140 cViper
 
24.03.20
14:04
(137) Да , я уже погуглил. Меня немного сбил с толку ваш комментарий про перебалансировку.
141 Salimbek
 
24.03.20
14:06
+ что касаемо читаемости кода - код, оптимизированный под производительность, будет чуть менее читаемым, с этим надо просто смириться.
142 sevod
 
24.03.20
14:08
(141) если переменным дать человеческие название, компилятор тормозить начнет? :) Переменные надо по человечески называть.
143 Кирпич
 
24.03.20
14:08
(132) Напиши на 1с, что ты хочешь сделать и покажи. Второй день выясняем, что тебе нужно, блин. :))
144 Salimbek
 
24.03.20
14:16
(142) Там, в коде, введенные мной, переменные prev и nz. Я не думаю, что мне стоит их как-то еще переименовывать. Того, что есть - достаточно.
145 yavasya
 
24.03.20
14:18
(135) строки как 1С
146 yavasya
 
24.03.20
14:20
(138) уже надеюсь что тролишь, ты не понимаешь, а учишь. тащи пожарный гидрант для себя.
http://profi1c.ru/products/fba_toolkit/kratkiy-vvodnyiy-kurs-v-java-dlya-programmista-1s.html#h3_10    

public void testTable(){

//таблица значений
        ArrayList<Row> table = new ArrayList<Row>();

        //добавить строку
        Row row = new Row("Значение1 в первой строке", 1, 123.45);
        table.add(row);
        …
        …

}

/*
* Строка таблицы
*/
public static class Row {
        String field1;
        int field2;
        double field3;

        Row(String field1, int field2, double field3) {
                this.field1 = field1;
                this.field2 = field2;
                this.field3 = field3;
        }
}
147 yavasya
 
24.03.20
14:21
(141) не вижу связи
148 ДНН
 
24.03.20
14:27
удалил хоть, нет?
149 Кирпич
 
24.03.20
14:46
(148) Я думаю, еще дня три :)
150 sevod
 
24.03.20
15:18
(146) а ты кроме "таблица значений" и "ArrayList" в состоянии что либо в этом коде понять? :) Там не утверждают что "таблица значений" == "ArrayList", там ее эмулируют с использованием "ArrayList" и класса Row. Я понимаю, что на форуме 1С поголовно у всех развиты телепатические способности, но не до такой же степени :)
Ну запихни ты в class Row, поле int index, и оно не будет меняться при удалении. Если ты это искал. Только это не ArrayList, хоть он тут и используется.
(149) Оптимист :)
151 Кирпич
 
24.03.20
15:21
(150) Интересно, как он в 1с удаляет пачками строки из таблицы значений. Такое вабще есть в 1с?
152 Кирпич
 
24.03.20
15:23
Наркоман наверное. Что со страной сделали....
153 Конструктор1С
 
24.03.20
15:59
(146) какая же это таблица значений? Если приближенно к 1с, это банальный массив структур получается
154 MadHead
 
24.03.20
16:18
(153) Я за sorted set.
155 Доктор Манхэттен
 
24.03.20
17:05
(105) >> В JS массивы - это скоере ассоциативный(индекс->значение) массив чем классический
C чего ты это взял?
156 Доктор Манхэттен
 
24.03.20
17:14
(132) >> ты правильно понял задачу

Что??? Ты всю ветку писал что нужно удалить по значениям индексов, тут вдруг чел пишет что он думал что нужно удалить по значениям элементов, и ты пишешь что так и надо? Зачем же тогда столько времени всем голову морочил индексами? Это абсолютно разные задачи. Почему ты не можешь написать полное условие задачи, чтобы было проще тебе помочь?
157 fisher
 
24.03.20
18:34
(146) Ну и покажи, как ты пробовал удалять по ссылке, что у тебя не получалось.
158 Доктор Манхэттен
 
24.03.20
19:30
Похоже ТС сам тролль, и пришел сюда вовсе не за помощью, раз даже не желает поделиться условием задачи.
159 sevod
 
24.03.20
20:49
(158)
Ну не, это же 1С форум. Тут же все телепаты :)
Шутки, шутками, но у меня уже давно привычка не читать внимательно ТЗ, не слушать внимательно пользователей. Опыт подсказывает, что все будет не так как они говорят/пишут. И если вдруг, о ужас, ты с нормальным человеком общаешься, то попадаешь в неприятную ситуацию.
160 Asmody
 
24.03.20
21:03
(158) Не, он не тролль, это он Битрикс на java пишет: Аналог Битрикс 24 на Java
161 v77
 
24.03.20
21:11
Понятно. Наркоман.
162 cViper
 
24.03.20
22:16
(160) Кстати, задача интересная, только во тя бы использовал другой язык программирования (фреймворк) для этого.
163 Asmody
 
24.03.20
22:18
(162) Пиши на Haskell.
164 cViper
 
25.03.20
00:26
(163) Мне вот в голову приходят только RoR и Django
165 Доктор Манхэттен
 
25.03.20
05:01
(164) Молодец, знаешь умные слова
166 strange2007
 
25.03.20
08:28
(0) >> В 1С для этого создается массив строк для удаления, и далее в метод удалить куда передается массив строк
Это неэффективный метод. Лучше коллекцию обходить с конца и по условиям удалять нужные строки.
167 Salimbek
 
25.03.20
08:35
(166) Применительно к java - лучше делать как в (128)
168 Кирпич
 
25.03.20
09:51
(167) Вот так будет проще, понятнее и памяти меньше жрать на больших списках. И по скорости будет не хуже (128)

    public static void removeAll(ArrayList<String> z, int[] ii) {
        if(ii.length==0) return;
        Arrays.sort(ii);
        for (int x = ii.length-1; x >= 0; x--) {
            z.remove(ii[x]);
        }      
    }
169 Salimbek
 
25.03.20
09:58
(168) Уверен? Понимаешь как работает remove на массиве Array?
170 Кирпич
 
25.03.20
10:00
(169) Уверен. Понимаю.
171 fisher
 
25.03.20
10:05
(168) Уже проходили. Самый эффективный вариант - использовать метод removeIf. Туда параметром можно передать прям предикат с условием удаления "строки" и он имеет оптимизацию для удаления пачки строк. Т.е. "схлопывает" массив не после удаления каждой строки (как делает remove), а один раз при удалении всех строк попадающих под условие удаления.
172 Кирпич
 
25.03.20
10:13
(171) верю. а в (128) точно пурга
173 Кирпич
 
25.03.20
10:16
(171) а как этот предикат нарисовать, имея список индексов, которые удалить надо? я в java только со вчерашнего дня :)
174 Salimbek
 
25.03.20
10:25
(172) Вот тебе код: https://pastebin.com/rhVcaNpk

Можешь или у себя или где в онлайн-компиляторах позапускать. Я на https://www.jdoodle.com/online-java-compiler/ попробовал 3 раза, выдало:

Kir:430090947
My : 17827987

Kir:410177305
My : 15280457

Kir:611930461
My : 25643564
175 fisher
 
25.03.20
10:26
(172) Почему пурга? Там как раз избегание "схлопывания" по remove за счет выделения дополнительной памяти. Немутабельная функция, все дела :) В теории должно быть быстрее. На практике утверждать не готов. Библиотечные функции могут использовать довольно эффективные оптимизации. Надо тестить.
176 Salimbek
 
25.03.20
10:26
(171) Код в (128) делает именно это.
177 fisher
 
25.03.20
10:29
(173) Так я готов поспорить, что ТС изначально не требуется удаление по списку индексов. Зуб даю (на самом деле нет), что он этот список индексов получил обходом коллекции и проверкой того самого условия.
178 fisher
 
25.03.20
10:32
(173) Для индексов тоже стопудово написать можно. Но "на гора" я его выдать не готов. Но было бы интересно сравнить производительность removeIf с (128)
179 Salimbek
 
25.03.20
10:46
(178) Типа такого: https://pastebin.com/BXpsByP6

Код из (128) я оставил (заполняю массив удаляемых значениями 0, 3, 6, 9, ...)
А для removeIf использовал условие (i%3)==0 что, по сути, делает то же самое, результат трех запусков:

RIf:64474782
My :26406079

RIf:57740917
My :19147529

RIf:48343494
My :15319765

Хотя немного соврал, мой код удаляет 30000 элементов, а revoveIf - 33333. Массив переделал на заполнение тоже 33333 элементов:

RIf:73238044
My :40056951

RIf:56954746
My :23337888

RIf:46069908
My :19952359
180 Кирпич
 
25.03.20
10:58
(174) И правда быстрее. Беру пургу обратно. Правда если удалять несколько элементов (штук десять), то (168) работает быстрее
181 Кирпич
 
25.03.20
11:04
+(180) вот на таком например

int[] myArray = new int[] {119,5689,12478,456,10,2896,369};
182 fisher
 
25.03.20
11:06
(180) В тесте Salimbek удаляет 30 тысяч из 100 тысяч :)
183 fisher
 
25.03.20
11:06
А для нескольких элементов - да, накладные расходы могут перекрывать профит.
184 Salimbek
 
25.03.20
11:48
(181) Вполне может быть, ведь "под капотом" remove, наверняка чистые блочные функции копирования данных. А в моем коде - addAll и z.subList() - вполне могут "вылетать" из блочного копирования.

+Посмотрел в OpenJDK / jdk8 / jdk8 / jdk - реализация addAll

        public boolean addAll(int index, Collection<? extends E> c) {
            rangeCheckForAdd(index);
            int cSize = c.size();
            if (cSize==0)
                return false;


            checkForComodification();
            parent.addAll(parentOffset + index, c);
            this.modCount = parent.modCount;
            this.size += cSize;
            return true;
        }

т.е. отдается классу выше. Смотрим реализацию в AbstactList, а там
        for (E e : c) {
            add(index++, e);
            modified = true;
        }
т.е. тупое поэлементное добавление. Не удивительно, что работает не быстро.

И subList выполняет
return new SubList(

т.е. опять же происходит ненужное создание доп. массива.
Но уходить на уровени ниже для оптимизации производительности - лениво.
185 MadHead
 
26.03.20
06:50
(179) А попробуйте поменять порядок запуска. Вначале ваш код, а потом уже сравниваемый. По крайней мере, если в IDEA выполнить последовательно 2 блока кода, то первый будет работать медленнее чем второй. Так как в начале "прогревается JVM"

В целом без требований к алгоритму удаления, сложно о чем-то говорить. Если нужно удалять большую часть, то лучше просто скопировать оставшиеся в новую коллекцию. Если удалять нужно мало элементов, то лучше итерироваться по коллекции с индексами для удаления. По умолчанию я бы написал что-то в духе (168)

        int[] toDelete = new int[]{1, 4, 2};
        ArrayList<Integer> list = Stream.of(1, 2, 3, 4, 5)
                .collect(Collectors.toCollection(ArrayList::new));

        Arrays.stream(toDelete)
                .boxed()
                .sorted(Collections.reverseOrder())
                .forEach((Integer i) -> list.remove(i.intValue()));

иначе - это преждевременная оптимизация.
186 MadHead
 
26.03.20
06:52
(185) Работать на стримах будет медленнее, за то более модно )
187 Salimbek
 
26.03.20
09:07
(186) На самом деле, там много различных влияющих факторов. Я ж побаловался потом еще немного с этой задачкой. В том числе сделал для себя вариант, когда начальный массив полностью выкидываем в обычный Array, а потом операциями блочного копирования собираем из него новый, не тратя время на оверхед в addAll и z.subList() На больших объемах удаляемых значений (ну типа удалить 30 000 из 100 000) и на мелких массивах (например удалить сколько-то из 1000 элементов) этот код работал быстрее, на каких-то размерах (например, удалить 200 из 100 000) - код с addAll выходил вперед, на каких-то простой remove быстрее отрабатывал (например удалить 10 из 30 000), зато этот remove вылетал по таймауту при попытке удалить 300 000 из 1 млн. элементов.
Причины такого поведения очень просты:
1) Потери кода с System.arrayCopy - идут на начальный переброс в массив всего списка, и, в конце, на переброс из этого массива обратно в ArrayList
2) Потери кода с addAll - идут на такое же неявное преобразование subList в Array и обратно, но тут меняются маленькие порции, и поэтому такой подход может быть быстрее, чем весь массив гонять туда-сюда, особенно, например, если удаляем 99 999 элементов из 100 000, в этом случае преобразование будет лишь у одного элемента, тогда как в коде 1) - весь массив будет дважды сконвертирован.
3) Потери кода с remove уходят на то, что для каждого удаляемого элемента создается копия всего массива (блочным копированием копируем часть данных _до_ удаляемого, и, потом, таким же блочным копированием копируем данные _после_, потом берем следующий элемент и повторяем. За счет прямого доступа к массиву - работаем очень быстро на малом количестве удаляемого). Но в случае с удалением 99 999 элементов из 100 000 - это будет полнейшей катастрофой.

Итого: самый оптимальный вариант - это создать свой класс-наследник от arrayList и внедрить туда алгоритм из 1) только без потерь на конвертацию. (потому как внутри все все равно лежит просто в массиве elementData, только извне доступа к нему нету).  Но это уже кун-фу более высокого порядка )))
188 Конструктор1С
 
26.03.20
09:57
(179) сомнительная экономия. Ради выигрыша в сотые доли секунды, вместо использования библиотечного метода писать свой портяночный метод. К тому же, выиграв во времени выполнения, ты можешь проиграть в расходовании вычислительных ресурсов
189 EVGA
 
26.03.20
11:05
(0) почему бы не так?
List<String> simpleList = Arrays.asList("test0", "test1", "test2", "test3", "test4", "test5");
simpleList.set(1, null);
simpleList.set(3, null);
simpleList.set(5, null);
simpleList.forEach(System.out::println);

вывод:
test0
null
test2
null
test4
null
190 Salimbek
 
26.03.20
11:10
(188) Вы о чем речь ведете?
1) Какой имеется "библиотечный метод", чтобы мы могли его использовать? Или надо написать код _используя_ библиотечные методы?
2) "Выигрыш в сотые доли секунды" - на каких объемах данных? Вот я попробовал удалить стандартным remove в массиве из 1 000 000 элементов 700 000 - так ответа и не дождался. Код работал более 10 секунд и вывалился по таймауту (а ставить себе java для этого баловства мне лень).

(189) Наверное, потому, что надо именно удалить. Например, в Списке по условию могут быть и null-элементы (какая-нибудь выборка с БД с left_join). Или код завязан на количество строк, Или... да пофиг, что там еще...
191 fisher
 
26.03.20
12:17
(179) Интересная инфа. Я думал, removeIf хуже себя поведет. А он вполне шустренько. Можно не заморачиваться в большинстве случаев.
192 MadHead
 
27.03.20
02:41
(187) В развлекательных целях интересное и полезное занятие, но в реальных задачаx тяга к оптимальному мешает.
(190) Из библиотек подобные операции умеет делать pandas, numpy (к примеру удалять элементы коллекции по булевому массиву), наверняка в DL4J предоставляет подобный функционал и под джаву. То что не дождались ответа, скорее особенность онлайн компилятора, который может под капотом на калькуляторе работать, так как у меня на домашнем ноуте фильтрация массива.

Фильтрация стримом 80мс на моем ноуте.

        Set<Integer> toDelete = IntStream.range(1, 1500000)
            .boxed()
            .collect(Collectors.toSet());
        ArrayList<Integer> list = IntStream.range(1, 3000000)
            .boxed()
            .collect(Collectors.toCollection(ArrayList::new));

        long startTime = System.currentTimeMillis();
        ArrayList<Integer> filtered = list.stream().filter(toDelete::contains).collect(Collectors.toCollection(ArrayList::new));

        long timeTaken = System.currentTimeMillis() - startTime;
        System.out.println("Time taken: " + timeTaken + ", new size: " + filtered.size());
193 cViper
 
27.03.20
04:01
(187) Зачем изобретать свой велосипед. Проше взять готовый опенсорс и использовать его.
(190) Если нет ограничений по памяти, то быстрее будет скопировать оставшиеся 300_000 элементов в новый список вместо удаления 700_000 из старого.
194 cViper
 
27.03.20
04:04
(190) Скиньте код сюда, интересно.
195 Конструктор1С
 
27.03.20
07:39
(190)
1. я имел ввиду, например, методы ArrayList
public boolean removeAll(Collection c)
public boolean removeIf(Predicate filter)
2. ну если много-много раз удалять через remove(int index) то конечно, можно и не дождаться. И вообще, если приходится таскать миллионы объектов в коллекциях, то это попахивает кривой архитектурой. Тут нужно думать не об написании своих методов с блэкджеком и шлюхами, взамен библиотечных, а о пересмотре архитектуры
196 Salimbek
 
27.03.20
10:15
(195) И removeAll и removeIf работают со _значениями_ а надо было с _индексами_. Почему - не ко мне вопрос, я лишь баловался с алгоритмами.

(193) "быстрее будет скопировать оставшиеся 300_000 элементов в новый список" Дык, мой код как раз и делает именно это.

И вообще,  слишком много времени уже занимает это теоретическое исследование, без практического выхлопу ))) Поэтому далее тута общаться уже лень. Надеюсь, вы меня понимаете )))
197 sevod
 
27.03.20
10:32
Тут уже Вася с форума удалился, а вы все еще никак ArrayList не можете :)
198 MadHead
 
27.03.20
11:20
(197) Вероятнее всего автор сам себе выкрутил яйца заложенным подходом.
199 fisher
 
27.03.20
18:56
(196) Я вот тоже поудивлялся. То ли cViper критиковал твой код в (128) даже не удосужившись его прочитать, то ли сетовал как раз на то, что он заточен на большую долю удаляемых элементов.
200 yavasya
 
27.03.20
19:06
(197) я здесь дорогой) . это ты не можешь) не смог видимо стать программистом ООП, поэтому тебя бомбит от людей которые делают
201 yavasya
 
27.03.20
19:07
(199) не умеешь , не берись, тем более не оценивай. cViper  было что то похожее на правду
202 GANR
 
27.03.20
20:39
203 Конструктор1С
 
28.03.20
05:04
(196) "надо было с _индексами_"

Очевидно, это какая-то тупая постановка задачи. Тем более, если стоит задача удалить дофига элементов из коллекции, то массив тут явно не подходит
204 sevod
 
28.03.20
11:56
(202) а на эту ссылку всех пускает?
205 sevod
 
28.03.20
12:21
(202)
hasNext() не поможет, если надо по индексам удалять. Индексы смещаются при удалении и перестают соответствовать тем индексам которые были в первоначальном массиве. Отсортировать массив индексов от большего к меньшему и удалять по ним. То есть снизу вверх. Самый простой алгоритм. При таком удалении, смещение нижестоящих элементов, не изменяет индексы вышестоящих. Если конечно ему именно это нужно было.
Но что бы дойти до такого супер сложного алгоритма, ему нужно свойства ArreyList прочитать, а не искать аналоги ArreyList в 1С.

(200) Я даже в 1С ООП использую :) Так что бросай Java и ползи назад в 1С. Ну или хотя бы свойства ArreyList для Java прочитай. А то так и будешь вопросы по Java на 1С форуме задавать.
206 sevod
 
28.03.20
12:30
(203) задача очень даже не тупая. Она для того что бы разобраться с особенностями ArreyList. У Васи например даже мысль возникла "Как сделать такую операцию в джава  чтобы индексы не сбивались ? Или остается строка с ссылкой null ?". На практике скорее всего действительно не нужна.
Искать аналоги в 1С не стоит. В 1С разработчики платформы сделали намного проще, но цена за это "скорость" 1С. Кому очень хочется, может разобраться с массивами в Си и адресной арифметикой в Си. Но для 1С это все лишнее.
207 Сияющий в темноте
 
28.03.20
14:59
нет
ну если отойти от программирования вообще и рассмотреть,скажем стопку из семи ящиков.
если мы удаляем пятый ящик,то можно как-то сохранить нумерацию?
очевидный ответ-нет,или мы вместо пятого ящика пихаем что-то его заменяющее или шестой ящик становится пятым.
а представьте,что кто-то захочет вставить ящик между вторым и третьим?

это,кстати,нашлядная модель поведенря индексов при изменении данных.
208 sevod
 
28.03.20
15:40
(207) ты сейчас расписал часть работы ArreyList :) Наверное Вася и ждал такого поста :)
Если взять для сравнения Arrey, то это комод с выдвигающимися ящиками. Нельзя добавить или уменьшить количество ящиков комода. Только заменить на новый комод. А вот в ArreyList очень даже можно. Его для этого и создавали. Правда ArreyList это тоже комод, поскольку "по капотом" там Arrey, но вот реально, кому нужно, найдут нормальную статью.
209 GANR
 
28.03.20
18:59
(205) Дак там по ссылке удалять можно же - никакие смещения не страшны

public static void main(String[] args) {

   ArrayList<Cat> cats = new ArrayList<>();
   Cat thomas = new Cat("Томас");
   Cat behemoth = new Cat("Бегемот");
   Cat philipp = new Cat("Филипп Маркович");
   Cat pushok = new Cat("Пушок");

   cats.add(thomas);
   cats.add(behemoth);
   cats.add(philipp);
   cats.add(pushok);
   System.out.println(cats.toString());

   cats.remove(philipp);

   System.out.println(cats.toString());
}

Вывод:

[Cat{name='Томас'}, Cat{name='Бегемот'}, Cat{name='Филипп Маркович'}, Cat{name='Пушок'}]
[Cat{name='Томас'}, Cat{name='Бегемот'}, Cat{name='Пушок'}]
210 sevod
 
28.03.20
19:08
(209) А нам по "Ссылке" (наверное правильнее "по значению") или по индексу? :) Вася какие то намеки делает, но интригу продолжает сохранять :)
211 Конструктор1С
 
28.03.20
19:15
(206) а чё в 1с не так? 1сные коллекции во многом похожы на джавовые. При этом 1сное соответствие хитро оптимизировано, т.к. на нём завязаны многие платформенные механизмы. И пожалуй соответствие даже будет попроизводительнее джавового аналога в виде интерфейса Map
212 Сияющий в темноте
 
28.03.20
19:35
(208)
на самом деле,ArrayList работает так:
при создании выделяется место,то есть создается комод на 4 ящика,все ящики заклеены,то есть не используются.
добааляется первый элемент-распечатывается первый ящик,
добавляется второй элемент-распечатывается второй ящик,
также третий-в третий ящик
теперь,если мы удаляем второй элемент,то мы должны выкинуть содержимое второго ящика
потом содержимое третьего ящика переложить во второй и заклеить третий ящик.

далее,если мы добавляем пятый элемент,то его засовывать некуда,система заказывает новый комод в два раза большего размера,перекладывает все существующие элементы и добавляет новый,а старый комод выбрасывается на помойку.
и,быть может,система повторого использования выдаст этот комод еще кому-то,а если нет,то сборщик мусора окончательно уничтожит его.

вот так.
на самом деле,насколько я помню,первоначально выделяется 16 элементов,а потом не в два раза,а на одну треть больше,но суть от этого не меняется.
213 Сияющий в темноте
 
28.03.20
19:52
и,на самом деле,если быть точным,то
в ящиках комода находятся дощечки,на которыз написан адрес(номер)обьекта,который саи размещается рядом с комодом,и мы не перемещаем дощечки,так как они в ящики встроены,а просто переписываем значение с одной дощечки на другую.
когда нам меняют комод,то старый остается стоять на том же месте,где и был,новый появляется рядом и где-то на дощечке номер старого комода меняется на новый.

опять же,место,где живут комоды и другие обьекты называется эдем-представим его ангаром.
ангаров таких в системе два,когда один заполняется,и новый обьект не всунуть,то сборщик мусора начинает просматривать таблички в ппмяти программы и переносит уапомчнутые там обьекты в новый ангар,к каждого переносимого обьекта он просматривает все таблички,чтобы перенести упомянутые там обьекты и так до тех пор,пока переносить будет нечего.
потом,все,что осталось в старом ангаре уничтожается,и старый ангар ждет следующей сборки мусора,где он будет принимающим.
214 sevod
 
28.03.20
20:17
Вот так Вася, вот так ссын. Добился таки своего. ArreyList уже разжевали :) Расписывайте Arrey, без него ArreyList будет не точным.
По моим данным, на старте пустой ArreyList это 10 ячеек, далее увеличение идет на коэффициент 1,5. Но по сути это не принципиально.

(211) проблема 1С в том, что нельзя по 1С учить java. Для изучения java, надо как ни странно читать документацию по java. Собственно и 1С по java учить тоже как то не очень умно. Но знание одного, может помочь с пониманием с другого. Но не всегда :)
215 Конструктор1С
 
29.03.20
08:09
Накатал тест https://pastebin.com/WE71dQPw

Создаётся коллекция определенного размера. В этой коллекции ищется 10% значений. Затем из коллекции удаляются 10% значений

Вывод: за поиск и удаление из ArrayList нужно бить по рукам. Эта коллекция не заточена под такие операции, и время вырастает пропорционально размеру массива. Но добавление значений в массив происходит очень быстро. Так что ArrayList нужно использовать как буфер

Количество = 100000
TestArray: заполнение коллекции - 0.001 сек.
TestArray: поиск в коллекции - 0.794 сек.
TestArray: удаление из коллекции - 1.184 сек.
TestMap: заполнение коллекции - 0.018 сек.
TestMap: поиск в коллекции - 0.005 сек.
TestMap: удаление из коллекции - 0.006 сек.

Количество = 500000
TestArray: заполнение коллекции - 0.002 сек.
TestArray: поиск в коллекции - 16.541 сек.
TestArray: удаление из коллекции - 21.863 сек.
TestMap: заполнение коллекции - 0.042 сек.
TestMap: поиск в коллекции - 0.021 сек.
TestMap: удаление из коллекции - 0.013 сек.

Количество = 1000000
TestArray: заполнение коллекции - 0.002 сек.
TestArray: поиск в коллекции - 65.444 сек.
TestArray: удаление из коллекции - 108.472 сек.
TestMap: заполнение коллекции - 0.073 сек.
TestMap: поиск в коллекции - 0.026 сек.
TestMap: удаление из коллекции - 0.025 сек.
216 Конструктор1С
 
29.03.20
08:13
+ сам я не джавист, поэтому мог нарукожопить. Но в целом результат должен быть близок к правде

TestArray - выполняет заполнение, поиск и удаление в ArrayList (аналог 1сного массива)
TestMap - выполняет заполнение, поиск и удаление в HashMap (аналог 1сного соответствия)
217 Конструктор1С
 
29.03.20
08:25
(214) учить-то джаву по 1с однозначно не стоит. Но вот насчет "тормознутости" 1сных коллекций я не уверен. Разработчики платформы 1с тоже не в носу ковыряются, и некоторые моменты заточили как надо
218 sevod
 
29.03.20
10:49
(217) я не писал про тормознутость 1С коллекций. В яве есть Arrey и ArreyList. Второй значительно удобнее перового и медленнее. 1С-ый массив по функционалу аналогичен ArreyList и он разумеется медленнее Arrey.
219 cViper
 
29.03.20
13:59
(215) Глянул код. СОздавать коллекции лучше с помощью конструктора и с предполагаемым размером количества элементов, чтобы избежать постоянного расширения. Это очень сильно влияет на производительность.
Выводы которые вы написали, они очевидны и без вашего теста.
(199) А я даже не вникал особо в код в (128) комментарии. Там говнокод написан. И мой комментарий из (193) относится исключительно к комментарию из (190).
220 yavasya
 
29.03.20
20:06
(218) потому что в ArrayList можно добавить строки в отличие от Array
221 v77
 
29.03.20
20:33
(218) Да напиши ты хоть раз Array вместо Arrey. Ёлки моталки.
222 sevod
 
29.03.20
23:23
(221) Да как я это тебе напишу?! Тут IDE нет! Эта IDEA сама за меня все пишет. Знаю что лучше что нибудь по проще, но лень.
(220) Молодца, прогрессируешь.
223 v77
 
30.03.20
09:23
(222) Ладно заливать. Не писал ты ничего и не читал. Потому и пишешь с ошибками.
224 fisher
 
30.03.20
09:55
(219) > А я даже не вникал особо в код в (128) комментарии
Да-да. Я заметил. На критику без "особого вникания" у вас времени полно. А на демонстрацию "как надо" примерами живого кода (что называется, вместо тысячи слов) времени не находится. Не царское это дело. Это ж, не дай бог, программировать придется. А там ведь и закритиковать могут.
225 cViper
 
31.03.20
01:27
(224)
1) Есть такие принципы, как SOLID. Один из этих принципов рекомендует писать код отталкиваясь от интерфейса. То есть, в примере 128 надо принимать аргумент типа List<String> и возвращать также List<String>, вместо ArrayList<String>. Это урочень джуна.
2) Именование переменных как z и ii недопустимо. Оно ничего не говорит тому, кто будет этот код читать. Это тоже урочень джуна.
3) Зачем использовать разные структуры данных для значений и индексов? Либо человек не понимает как они работают, либо просто не знает как отсортировать List стандартными средствами jdk.

Сам код, думаю, корректен. Но ковыряться в нем мне не интересно. Как можно решить задачу с индексами и с сохранением позиций я писал в одном из комментариев. Там настолько все просто, что не вижу смысло писать имлементацию.
226 Sserj
 
31.03.20
03:42
(215) На самом деле не очень правильный тест применительно к топику.
В тесте удаление происходит через removeAll с коллекцией объектов. А это очень нехороший метод, посмотрев исходники ArrayList можно увидеть:
        final Object[] es = elementData;
        int r;
        // Optimize for initial run of survivors
        for (r = from;; r++) {
            if (r == end)
                return false;
            if (c.contains(es[r]) != complement)
                break;
        }

Т.е. поиск ведется перебором массива ArrayList и поиском каждого элемента в переданной коллекции.
В топике задача была на удаление по индексу, опять же посмотрев исходники ArrayList видим метод удаления по индексу:
        modCount++;
        final int newSize;
        if ((newSize = size - 1) > i)
            System.arraycopy(es, i + 1, es, i, newSize - i);
        es[size = newSize] = null;

Тобишь фактически выполняется только System.arraycopy, которая в свою очередь является лишь оберткой над системной memcopy.
Удаление по индексу в итоге будет не сильно отличаться по скорости от времени заполнения коллекции в тесте.
227 fisher
 
31.03.20
09:10
(225) > настолько все просто, что не вижу смысло писать имлементацию
Ну вот опять. Чужой код настолько очевидно бездарен, что даже нет смысла в нем разбираться. А свой код настолько прост и самоочевидно идеален, что даже нет смысла его писать :)
А вы возьмите и напишите. И другим наука будет на конкретном примере и вы без критики не останетесь. Авось тоже польза будет.
228 v77
 
31.03.20
09:50
(225) "Там настолько все просто, что не вижу смысло писать имлементацию."
Это типа "моя фамилия слишком известна, чтобы я её называл" :))
229 Sserj
 
31.03.20
10:37
(225) "..Именование переменных как z и ii недопустимо. Оно ничего не говорит тому, кто будет этот код читать. Это тоже урочень джуна.."
хихи. В (226) выдержка из исходников jdk:
        int r;
        // Optimize for initial run of survivors
        for (r = from;; r++) ...
Можешь смело утверждать что стандартную библиотеку явы писали джуны-лузеры :)
230 Конструктор1С
 
31.03.20
15:23
(229) тем не менее, имена классов и объектов стандартных библиотек выбраны лаконично, интерфейсы хорошо задокументированы. Стандартную библиотеку дорабатывает только оракл, внуть библиотеки нырять не принято, разве что из интереса "что там под капотом". А вот твой код будут читать и дорабатывать другие программисты, которым односимвольные переменные будут не понятны. Поэтому всегда нужно выбирать хорошие описательные имена переменных/методов/классов
231 Конструктор1С
 
31.03.20
15:27
+кстати, имена переменных-счетчиков допускается делать короткими, вплоть до одного символа: i, j, k. Но это "так исторически сложилось". А вообще, чем больше область видимости у переменной, тем тщательнен должно быть выбрано её имя
232 fisher
 
01.04.20
09:28
(230) Строго говоря, описательные имена переменных больше касаются прикладного программирования. А в системном программировании и системных алгоритмах имена переменных часто не несут большого смысла достойного имен СКД во-первых (речь часто просто о тасовании безликих ячеек памяти), во-вторых - их количество обычно невелико в области видимости, в-третьих - они часто используются. Поэтому сплошь и рядом используют односимвольные/двухсимвольные имена переменных. Как раз для повышения читабельности, как бы на первый взгляд это парадоксально не звучало.
233 Конструктор1С
 
02.04.20
05:20
(232) тут скорее тоже "так исторически сложилось". Многие низкоуровневые ЯП имели ограничение на длину имен переменных