Удаление элементов из списка

При переходе по списку я хотел бы удалить элемент списка в зависимости от условия. См. Код ниже.

Это дает мне исключение ConcurrentModification.

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

Как это можно сделать?

Ответ 1

Вам нужно использовать Iterator и вызвать remove() на Iterator вместо использования цикла for.

Ответ 2

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

Создание дополнительного предположения, что список имеет строки. Как уже было сказано, требуется list.iterator(). listIterator может сделать немного навигации.

Ответ 3

Вы не можете этого сделать, потому что вы уже зацикливаете на нем.

Чтобы избежать этой ситуации, используйте Iterator, который гарантирует, что вы удалите элемент из списка безопасно...

List<Object> objs;
Iterator<Object> i = objs.iterator();
while (i.hasNext()) {
   Object o = i.next();
  //some condition
    i.remove();
}

Ответ 4

Вы не можете и не должны изменять список во время итерации по нему. Вы можете решить эту проблему, временно сохраняя объекты для удаления:

List<Object> toRemove = new ArrayList<Object>();
for(Object a: list){
    if(a.getXXX().equalsIgnoreCase("AAA")){
        toRemove.add(a);
    }
}
list.removeAll(toRemove);

Ответ 5

Помимо превосходных решений, предлагаемых здесь, я хотел бы предложить другое решение.

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

В коде я заменил тип List на T, так как я не знаю, на что напечатан ваш список.

Эта проблема может быть решена с помощью guava следующим образом:

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

И где-то еще вы определяете XXX_EQUAL_TO_AAA как:

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

Однако это, вероятно, слишком велико в вашей ситуации. Это то, что становится все более мощным, чем больше вы работаете с коллекциями.

Ohw, вам также нужны эти статические импорта:

import static com.google.common.base.Predicates.not;
import static com.google.common.collect.Collections2.filter;

Ответ 6

//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);