Итерация по коллекции, избегая исключения ConcurrentModificationException при удалении объектов в цикле - PullRequest
1120 голосов
/ 22 октября 2008

Мы все знаем, что вы не можете сделать это:

for (Object i : l) {
    if (condition(i)) {
        l.remove(i);
    }
}

ConcurrentModificationException и т. Д. ... это иногда работает, но не всегда. Вот некоторый конкретный код:

public static void main(String[] args) {
    Collection<Integer> l = new ArrayList<>();

    for (int i = 0; i < 10; ++i) {
        l.add(4);
        l.add(5);
        l.add(6);
    }

    for (int i : l) {
        if (i == 5) {
            l.remove(i);
        }
    }

    System.out.println(l);
}

Это, конечно, приводит к:

Exception in thread "main" java.util.ConcurrentModificationException

... хотя несколько потоков этого не делают ... Во всяком случае.

Как лучше всего решить эту проблему? Как я могу удалить элемент из коллекции в цикле, не выбрасывая это исключение?

Я также использую здесь произвольный Collection, не обязательно ArrayList, поэтому вы не можете полагаться на get.

Ответы [ 23 ]

0 голосов
/ 19 июля 2018
Collection<Integer> l = new ArrayList<Integer>();//Do the collection thing...

l.removeIf(i -> i == 5);      //iterates through the collection and removes every occurence of 5

Лямбда-выражения и методы Collection в Jdk 8 включены в Handy и добавляют синтаксический сахар.

Метод removeIf перебирает коллекцию и фильтрует с помощью Предиката. Предикат является функцией аргумента, который возвращает логическое значение ... Так же, как boolean _bool = (str) -> str.equals("text");

0 голосов
/ 12 октября 2013

это может быть не лучшим способом, но для большинства небольших случаев это должно быть приемлемо:

"создать второй пустой массив и добавить только те, которые вы хотите сохранить"

Я не помню, откуда я это прочитал ... для справедливости я сделаю эту вики в надежде, что кто-то найдет ее или просто не заработает репутацию, которую я не заслуживаю.

0 голосов
/ 30 июня 2016
for (Integer i : l)
{
    if (i.intValue() == 5){
            itemsToRemove.add(i);
            break;
    }
}

Подвох после удаления элемента из списка, если вы пропустите внутренний вызов iterator.next (). это все еще работает! Хотя я не предлагаю писать такой код, это помогает понять концепцию, стоящую за ним: -)

Ура! * * 1004

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...