Ответ
ConcurrentModificationException — это runtime-исключение, которое возникает при некорректной модификации коллекции во время её итерации (кроме случаев, когда модификация выполняется через методы самого итератора). Это часть механизма fail-fast, предназначенного для предотвращения недетерминированного поведения.
Типичная причина (однопоточный случай):
List<String> list = new ArrayList<>(Arrays.asList("A", "B", "C"));
for (String item : list) { // Неявно использует Iterator
if (item.equals("B")) {
list.remove(item); // МОДИФИКАЦИЯ КОЛЛЕКЦИИ ВНЕ ИТЕРАТОРА -> ИСКЛЮЧЕНИЕ!
}
}
Правильные способы удаления элементов во время итерации:
- Использовать
Iterator.remove():Iterator<String> iterator = list.iterator(); while (iterator.hasNext()) { String item = iterator.next(); if (item.equals("B")) { iterator.remove(); // Безопасное удаление через итератор } } - Использовать методы коллекции с Java 8+:
list.removeIf(item -> item.equals("B")); - Собрать элементы для удаления и выполнить операцию после итерации.
Многопоточный контекст: Исключение также может быть выброшено, если один поток изменяет коллекцию, в то время как другой выполняет по ней итерацию. Для безопасной работы в многопоточной среде используйте:
ConcurrentHashMap,CopyOnWriteArrayList.- Явную синхронизацию блоков кода, работающих с коллекцией.