Ответ 1
Вам нужно использовать Iterator
и вызвать remove()
на Iterator
вместо использования цикла for
.
При переходе по списку я хотел бы удалить элемент списка в зависимости от условия. См. Код ниже.
Это дает мне исключение ConcurrentModification
.
for (Object a : list) {
if (a.getXXX().equalsIgnoreCase("AAA")) {
logger.info("this is AAA........should be removed from the list ");
list.remove(a);
}
}
Как это можно сделать?
Вам нужно использовать Iterator
и вызвать remove()
на Iterator
вместо использования цикла for
.
for (Iterator<String> iter = list.listIterator(); iter.hasNext(); ) {
String a = iter.next();
if (...) {
iter.remove();
}
}
Создание дополнительного предположения, что список имеет строки.
Как уже было сказано, требуется list.iterator()
. listIterator может сделать немного навигации.
Вы не можете этого сделать, потому что вы уже зацикливаете на нем.
Чтобы избежать этой ситуации, используйте Iterator, который гарантирует, что вы удалите элемент из списка безопасно...
List<Object> objs;
Iterator<Object> i = objs.iterator();
while (i.hasNext()) {
Object o = i.next();
//some condition
i.remove();
}
Вы не можете и не должны изменять список во время итерации по нему. Вы можете решить эту проблему, временно сохраняя объекты для удаления:
List<Object> toRemove = new ArrayList<Object>();
for(Object a: list){
if(a.getXXX().equalsIgnoreCase("AAA")){
toRemove.add(a);
}
}
list.removeAll(toRemove);
Помимо превосходных решений, предлагаемых здесь, я хотел бы предложить другое решение.
Я не уверен, что вы можете добавлять зависимости, но если можете, вы можете добавить 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;
//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);