Вход | Регистрация
    1  2  3   

Java. Удалить в ArrayList массив строк.

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

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

   yavasya
 
38 - 23.03.20 - 13:51
(37) я тоже так могу копировать код с форумов. ищу оптимальное решение
   Кирпич
 
39 - 23.03.20 - 13:52
(38) я не копировал. я сам.
   yavasya
 
40 - 23.03.20 - 13:54
(39) ты ж в первый раз в жизни видишь
   fisher
 
41 - 23.03.20 - 13:56
(36) Я читаю с начала и тоже нифига не понимаю.
   Кирпич
 
42 - 23.03.20 - 13:57
(40) ПИШУ, а не ВИЖУ
   Salimbek
 
43 - 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) Так или не так?
   yavasya
 
46 - 23.03.20 - 14:12
(45) все верно
   yavasya
 
47 - 23.03.20 - 14:16
(43) 1) "В 1С для этого создается массив строк для удаления, и далее в метод удалить куда передается массив строк." - где вы такое нашли? А если этого нету, то для чего выдумывать несуществующие сущности? Вы тролите ? С таблицами значений не работали ?
2) "Как сделать такую операцию в джава  чтобы индексы не сбивались ? не прочитали ничего
3) "Или остается строка с ссылкой null ?" - если вы строку удалили, то null не будет. Это ваше сугоболичное не начем не основанное убеждение
   Кирпич
 
48 - 23.03.20 - 14:16
(46) Ну вот тебе решение в (37)
Но лучше использовать HashMap вместо ArrayList
   yavasya
 
49 - 23.03.20 - 14:18
(48) видимо так . или по значению строки удалять
   Salimbek
 
50 - 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) Самый эффективный вариант вам уже сказали - делать копию массива и туда переносить элементы из первого, за исключением тех, кто в вашем списке. При этом можно будет использовать команды копирования блоков данных, которые очень эффективно компилируются.
   yavasya
 
51 - 23.03.20 - 14:22
(50) перебрать с конца уже было.
амый эффективный вариант вам уже сказали - делать копию массива и туда переносить элементы из первого, за исключением тех, кто в вашем списке. При этом можно будет использовать команды копирования блоков данных, которые очень эффективно компилируются. Здесь я с вами соглашусь.
   fisher
 
52 - 23.03.20 - 14:24
Вообще лучше всего использовать removeIf и туда засунуть предикат условия на удаление.
Так хотя бы "схлопывание" массива будет выполнено за один присест.
   Конструктор1С
 
53 - 23.03.20 - 14:26
(0) а как ты пришел к тому, что тебе нужно удалить конкретные индексы? Правильнее всё-таки удалять объекты. И если ты получил индексы, то где-то чуть раньше работал с объектами
   DionisSergeevich
 
54 - 23.03.20 - 14:28
Это форум про аниме? Как пропатчить кде под фрибсд?))
   yavasya
 
55 - 23.03.20 - 14:29
(53) если удалишь строку, то поплывут индексы. Про это.
   Salimbek
 
56 - 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;

Можно переделать этот алгоритм и на множество элементов.
   fisher
 
57 - 23.03.20 - 14:32
(53) Насколько я понял, он хотел по аналогии с удалением строк таблицы значений по ссылкам сделать (в сабже он про это писал). Но запутался в своей эмуляции ТЗ на вложенных списках, не смог этого сделать и попытался через индексы. А то, что можно прямо в процедуру удаления передать ссылку на функцию с условием удаления он догадаться не смог, потому что в 1С таких вариантов нет.
   yavasya
 
58 - 23.03.20 - 14:37
(57) блин, да это легко написать. я не знаю как правильно
   yavasya
 
59 - 23.03.20 - 14:39
(56) ну да, это с конца способ перебрать
   yavasya
 
60 - 23.03.20 - 14:42
(57) прямо в процедуру удаления передать ссылку на функцию с условием удаления. а это как ?
   Salimbek
 
61 - 23.03.20 - 14:43
(59) Вы внимательно уловили суть этого алгоритма? Там нету ни удаления, ни перебора с конца.
   yavasya
 
62 - 23.03.20 - 14:46
(61) сделать копию массива и туда переносить элементы из первого, за исключением тех, кто в вашем списке.
   yavasya
 
63 - 23.03.20 - 14:46
(61) там нативная библиотека и она очень быстро работает
   fisher
 
64 - 23.03.20 - 14:48
(60) См. (52)
   Salimbek
 
65 - 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));
      
    }
   yavasya
 
66 - 23.03.20 - 14:51
(65) ты ооп пишешь ? лямда выражение массивы, бинарные деревья
 
 Рекламное место пустует
   Salimbek
 
67 - 23.03.20 - 14:51
(62) ну почти, только копии массива не создается, а текущие элементы переписываются
   Salimbek
 
68 - 23.03.20 - 14:52
(66) Ты у меня на счет кода (65) спрашиваешь или вообще?
   yavasya
 
69 - 23.03.20 - 14:52
вообще
   fisher
 
70 - 23.03.20 - 14:54
(65) Я подозреваю, что к списку индексов для удаления он пришел от безысходности. И в лямбде ему нужно просто свое условие прописать.
Но вариант красивый. Чувствуется практический опыт в java :)
   fisher
 
71 - 23.03.20 - 14:59
(66) Arrays.binarySearch - это аналог Найти() в массиве 1С. А лямбды в java - это просто синтаксический сахар вокруг объектов. Просто чтобы писанины было меньше.
   Salimbek
 
72 - 23.03.20 - 14:59
(69) Вообще пишу на том, на чем удобно

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

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

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

z.removeIf(el -> el.isDeleted)

ну или как оно там к полям коллекции обращается...
   fisher
 
81 - 23.03.20 - 15:38
(80) Чем выгоднее? Почему в предикате не проверять все что надо? Разве что для повышения читабельности, если там совсем что-то хитровымученное.
   Salimbek
 
82 - 23.03.20 - 15:44
(81) Выгоднее, например, тем, что isDeleted можно и в графической форме дать юзеру проставлять, да и вообще, isDeleted это как раз по 1С-ному ))) А так - согласен, чем меньше беготни по массиву, тем быстрее все работает.
   Доктор Манхэттен
 
83 - 23.03.20 - 16:59
(0) Если в массиве важны индексы, то это явный признак того, что массив используете не по назначению. Индексы массива не должны нести никакой смысловой нагрузки. При правильно спроектированном коде, индексы не используются в принципе.
   MadHead
 
84 - 23.03.20 - 18:32
Всю ветку не читал.
По классике правильнее всего удалить через итератор (понадобиться переменная которая определяет четный/не четный)
   Доктор Манхэттен
 
85 - 23.03.20 - 22:06
(0) В чем вообще суть задачи? По какому условию нужно удалять элементы, и для чего впоследствии нужны индексы? Напиши полностью что ты хочешь сделать.
   cViper
 
86 - 23.03.20 - 22:20
(0) Используй массив вместо листа.
   cViper
 
87 - 23.03.20 - 22:30
(14) ArrayList - это реализация интерфейса List на базе массива.
А то что таблица значений, это либо HashMap либо просто ArrayList<ArrayList<String>> либо String[][],  смотря что тебе надо.
(37) Лучше бы не писал *)
(0) Положи в HashSet значения которые надо удалить. Итерирую массив значений проверяй if(set.contains(value)) то переписывай значение мссива на null.
   cViper
 
88 - 23.03.20 - 22:35
(0) Еще, как вариант, если в твоем листе только положительные числа, то модешь им добавлять знак -. Тогда и ндексы сохранишь и значения предыдущие будут.
   MadHead
 
89 - 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] и применить фильтр.
   cViper
 
90 - 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, нужно из него удалить все нечетные элементы".
   MadHead
 
94 - 23.03.20 - 23:24
(93) Это довольно частый вопрос на собесах и синтетических задачах.
К примеру можно представить, что нужно получить часть данных или алгоритм игры требует такого удаления.
   MadHead
 
95 - 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 наверняка есть аналог такой функции.
   cViper
 
99 - 24.03.20 - 02:15
(92) При расширении или сужении массива никакого копирования не проиходит. Просто обьекты переносятся в массив нового размера. Эта процедура очень быстрая, выполняется нативный код System.arrayCopy. А старый обьект массива удалится сборщиком мусора.
   Конструктор1С
 
100 - 24.03.20 - 03:42
(55) обычно индексы массива интересуют только сам массив. А если не только сам массив, то это кривой алгоритм
  1  2  3   

Список тем форума
Рекламное место пустует  Рекламное место пустует
ВНИМАНИЕ! Если вы потеряли окно ввода сообщения, нажмите Ctrl-F5 или Ctrl-R или кнопку "Обновить" в браузере.