Ответ
При изменении коллекции во время итерации по ней (не через методы итератора) выбрасывается ConcurrentModificationException.
Механизм: Это часть контракта fail-fast итераторов. Итератор проверяет, что внутренний счетчик модификаций коллекции (modCount) не изменился с момента его создания. Любое структурное изменение коллекции (добавление, удаление) увеличивает этот счетчик. Если итератор обнаруживает расхождение, он немедленно выбрасывает исключение.
Пример возникновения:
List<Integer> numbers = new ArrayList<>();
numbers.add(1);
numbers.add(2);
for (Integer num : numbers) { // Неявно создается итератор
if (num == 1) {
numbers.add(3); // Прямое изменение коллекции -> Исключение!
}
}
Способы безопасного изменения во время итерации:
- Использовать
Iterator.remove():Iterator<Integer> it = numbers.iterator(); while (it.hasNext()) { Integer num = it.next(); if (num == 1) { it.remove(); // Безопасно } } - Создать копию коллекции для итерации: Итерироваться по копии, изменять оригинал.
- Использовать
CopyOnWriteArrayList: Эта коллекция создает новую копию внутреннего массива при каждой модификации, что позволяет безопасно итерироваться по старой копии.