|
Java. Удалить в ArrayList массив строк. | ☑ | ||
---|---|---|---|---|
0
yavasya
23.03.20
✎
12:18
|
Допустим мне в ArrayList нужно удалить 1,3,5 строку. В 1С для этого создается массив строк для удаления, и далее в метод удалить куда передается массив строк. Как сделать такую операцию в джава чтобы индексы не сбивались ? Или остается строка с ссылкой null ?
|
|||
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)
|
|||
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) тут скорее тоже "так исторически сложилось". Многие низкоуровневые ЯП имели ограничение на длину имен переменных
|
Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |