Удаление элемента во время итерации. удалить, если результат в ConcurrentModificationException - PullRequest
2 голосов
/ 13 февраля 2020

Я пытаюсь удалить элементы из набора (someObjectSet), проходя через него. Как я гуглил, при использовании removeIf следует избегать исключения ConcurrentModificationException в этом случае. Однако это не работает для меня.

Google соврал мне (или я неправильно понял), или я не правильно использую removeIf?

Set<SomeObject> someObjectSet = new HashSet<>();
someObjectSet.add(obj1);
someObjectSet.add(obj2);
someObjectSet.add(obj3);

for (SomeObject obj : someObjectSet ){
    ...
    someObjectSet.removeIf(ele -> if ele satisfies some condition)
}


Причина, по которой я хочу do remove, если внутри l oop указано, что в каждом l oop можно определить, что некоторым другим элементам набора больше не нужно go в l oop, поэтому я удаляю его так что для l oop их больше не заберут.

Например,
В цикле 1 выбирается obj1.
Затем в том же l oop он обнаруживает, что obj2 нет больше нужно обрабатывать => удалить obj2 из набора.
В цикле 2 вместо obj2 берется obj3

Заранее спасибо!

1 Ответ

2 голосов
/ 13 февраля 2020

Не повторять и removeIf использовать элементы вашей итерации. Помимо проблемы, с которой вы сейчас сталкиваетесь, эти вызовы сводятся к повторению всей коллекции для каждого элемента коллекции (поэтому вы все еще удаляете из коллекции во время итерации, что объясняет исключение!).

removeIf выполняет итерации для вас, поэтому все, что вам нужно, это предикат SomeObject:

//no loop
someObjectSet.removeIf(ele -> if ele satisfies some condition);

, где ele -> if ele satisfies some condition - это условие, что каждый SomeObject элемент будет проверен на соответствие (те, кто пройдет тест, будут удалены). forEach организует тест для всех элементов в someObjectSet, вам не нужно это делать.


Если у вас возникло вторичное условие, на основе которого вы хотите удалить элементы, затем вы можете составить предикаты (с or), как в этом примере:

Set<Integer> set = new HashSet<>(Set.of(1, 2, 3, 4, 5, 6, 7, 8, 9));

Predicate<Integer> predicate = s -> s % 2 == 0;
Predicate<Integer> predicate2 = predicate.or(s -> s % 3 == 0);
set.removeIf(predicate2);

// Test with set.removeIf(predicate);
// then with set.removeIf(predicate2);
// and compare results
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...