Вопрос проверяет понимание механизма for-each, итераторов и fail-fast поведения коллекций.
При удалении элемента из коллекции внутри for-each обычно выбрасывается ConcurrentModificationException.
Это происходит потому, что for-each использует Iterator под капотом.
Удаление напрямую через коллекцию нарушает ожидаемое состояние итератора.
Итератор обнаруживает несогласованную модификацию.
Такое поведение защищает коллекцию от некорректного обхода.
Чтобы понять причину исключения, важно знать, как работает for-each.
Цикл:
for (String s : list) {
// ...
}
Компилятор преобразует в:
Iterator<String> it = list.iterator();
while (it.hasNext()) {
String s = it.next();
// ...
}
Если внутри цикла вызвать:
list.remove(s);
происходит следующее:
Коллекция меняет свою структуру
Итератор об этом «не знает»
При следующем next() или hasNext() итератор обнаруживает рассинхронизацию
Большинство стандартных коллекций:
хранят счётчик структурных изменений
сравнивают его с ожидаемым значением в итераторе
выбрасывают исключение при расхождении
Использовать Iterator.remove()
Использовать removeIf()
Использовать потокобезопасные коллекции при необходимости
for-each нельзя использовать для удаления элементов напрямую из коллекции — это приведёт к ошибке времени выполнения.