Видалення елементів зі списку

Поки цитуючи список, я хотів би видалити елемент списку залежно від стану. Переглянути код нижче.

Це дає мені виняток ConcurrentModification .

for (Object a : list) {
    if (a.getXXX().equalsIgnoreCase("AAA")) {
        logger.info("this is AAA........should be removed from the list ");
        list.remove(a);
    }
}

Як це можна зробити?

87
Ви не можете видалити елемент зі списку, коли ви повторюєте цей список. Замість цього скопіюйте і видаліть елементи, або виконайте це безпосередньо до ітератора.
додано Автор thegrinner, джерело
Використовуючи Java 8, найбільш ефективним способом цього є використання методу removeIf (предиката) у списку.
додано Автор Holly Cummins, джерело
Використовуючи Java 8, найбільш ефективним способом цього є використання методу removeIf (предиката) у списку.
додано Автор Holly Cummins, джерело

8 Відповіді

for (Iterator iter = list.listIterator(); iter.hasNext(); ) {
    String a = iter.next();
    if (...) {
        iter.remove();
    }
}

Зробіть додаткове припущення, що список містить рядки. Як вже відповіли, потрібен list.iterator() . listIterator може зробити трохи навігація теж.

185
додано

Вам потрібно скористатись Iterator і зателефонувати за remove() на iterator замість використання циклу для .

62
додано

Вам потрібно скористатись Iterator і зателефонувати за remove() на iterator замість використання циклу для .

62
додано

Ви не можете зробити це, тому що ви вже циклу на це.

Щоб запобігти цій ситуації, використовуйте Iterator, що гарантує вам безпечно видалити елемент із списку ...

List objs;
Iterator i = objs.iterator(); while (i.hasNext()) { Object o = i.next(); //some condition i.remove(); } 
27
додано

Ви не можете і не повинні змінювати список, повторюючи його. Ви можете вирішити це, тимчасово зберігаючи об'єкти для видалення:

List toRemove = new ArrayList(); for(Object a: list){ if(a.getXXX().equalsIgnoreCase("AAA")){ toRemove.add(a); } } list.removeAll(toRemove); 
15
додано
@AlexVentura Це пов'язано з тим, як працює ітератор. Якщо список ітераторських посилань змінює (особливо це розмір), то без ітератора, який знає, ітератор буде "переплутано".
додано Автор André Stannek, джерело
Чому я не можу і не повинен змінювати список під час повторення над ним?
додано Автор Alex Ventura, джерело

Крім всіх чудових рішень, запропонованих тут, я хотів би запропонувати інше рішення.

Я не впевнений, що ви можете додавати залежностей, але, якщо можете, ви можете додати https://code.google.com/p/guava-libraries/ як залежність. Ця бібліотека додає підтримку багатьох базових функціональних операцій для Java і може зробити роботу з колекціями набагато простішою та зручнішою.

У коді я замінив тип списку на T, оскільки я не знаю, до чого набирається ваш список.

Ця проблема може бути вирішена з гуавою так:

List filteredList = new Arraylist<>(filter(list, not(XXX_EQUAL_TO_AAA)));

І десь ще ви визначите XXX_EQUAL_TO_AAA як:

public static final Predicate XXX_EQUAL_TO_AAA = new Predicate() {
    @Override
    public boolean apply(T input) {
        return input.getXXX().equalsIgnoreCase("AAA");
    }
}

Однак, це, напевно, надмірна ваша ситуація. Це просто те, що стає все більш потужним, тим більше ви працюєте з колекціями.

Ну, також, вам потрібен цей статичний імпорт:

import static com.google.common.base.Predicates.not;
import static com.google.common.collect.Collections2.filter;
7
додано
//first find out the removed ones

List removedList = new ArrayList();
for(Object a: list){
    if(a.getXXX().equalsIgnoreCase("AAA")){
        logger.info("this is AAA........should be removed from the list ");
        removedList.add(a);

    }
}

list.removeAll(removedList);
3
додано
Чому так складно ...
додано Автор m0skit0, джерело
Ви створюєте новий об'єкт, коли вам це не потрібно, і, можливо, цикл у два рази.
додано Автор m0skit0, джерело
Його не складно. Його ще один спосіб видалити один список з іншого.
додано Автор Makky, джерело
//first find out the removed ones

List removedList = new ArrayList();
for(Object a: list){
    if(a.getXXX().equalsIgnoreCase("AAA")){
        logger.info("this is AAA........should be removed from the list ");
        removedList.add(a);

    }
}

list.removeAll(removedList);
3
додано
Чому так складно ...
додано Автор m0skit0, джерело
Ви створюєте новий об'єкт, коли вам це не потрібно, і, можливо, цикл у два рази.
додано Автор m0skit0, джерело
Його не складно. Його ще один спосіб видалити один список з іншого.
додано Автор Makky, джерело
ІТ КПІ - Java
ІТ КПІ - Java
436 учасників