Этот вопрос проверяет знание механизмов итерации и защиты коллекций от некорректных изменений.
Безопасно удалять элементы можно через Iterator.remove().
Прямое удаление из коллекции во время обхода приводит к ошибке.Iterator знает о своём текущем состоянии и корректно обновляет его.
Это предотвращает ConcurrentModificationException.
Другие способы зависят от типа коллекции.
При обходе коллекции важно не нарушать её внутреннее состояние.
Большинство коллекций Java используют механизм fail-fast:
коллекция отслеживает структурные изменения
при несогласованной модификации выбрасывается исключение
IteratorIterator<String> it = list.iterator();
while (it.hasNext()) {
String value = it.next();
if (value.equals("remove")) {
it.remove();
}
}
Почему это работает:
Iterator синхронизирован с состоянием коллекции
изменение происходит через него самого
list.remove()for (String s : list) {
list.remove(s); // ошибка
}
Причины:
for-each использует Iterator
коллекция меняется «в обход» итератора
В зависимости от задачи:
использование removeIf()
работа с копией коллекции
потокобезопасные коллекции (CopyOnWriteArrayList)
Безопасное удаление во время обхода возможно только через предусмотренные API, чаще всего через Iterator.remove().