


Чтобы удалить текущий элемент изменяемого ArrayList во время обхода, используйте remove() того итератора, который выдал элемент через next(). На Mentoring.digital разберём этот контракт на списке чисел и отдельно проверим ошибочные последовательности вызовов.
Возьмём список, в котором нужно оставить только неотрицательные числа. Iterator хранит состояние обхода, а его remove удаляет последний выданный элемент.
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class RemoveNegative {
public static void main(String[] args) {
List<Integer> values = new ArrayList<>(
List.of(3, -1, -2, 5, 0)
);
Iterator<Integer> iterator = values.iterator();
while (iterator.hasNext()) {
int value = iterator.next();
if (value < 0) {
iterator.remove();
}
}
System.out.println(values); // [3, 5, 0]
}
}
Вложенные отрицательные значения здесь соседствуют намеренно. Решение не пропускает второе из них из-за ручного увеличения индекса. Обёртка ArrayList нужна потому, что список, возвращаемый List.of, не поддерживает изменение.
Вызов разрешён только после next и не более одного раза для последнего выданного элемента. Вызов до первого next или повторный remove без нового next приводит к IllegalStateException, если итератор поддерживает удаление.
Удаление является необязательной операцией интерфейса Iterator. Итератор конкретной коллекции может выбросить UnsupportedOperationException. Наличие метода в интерфейсе не означает, что любой источник данных можно менять этим способом.
Не вызывайте values.remove(...) параллельно с этим обходом и не изменяйте список через второй итератор. Общий контракт Iterator не определяет поведение при внешнем изменении коллекции, если её документация не задаёт отдельную политику.
Исключение ConcurrentModificationException в знакомом цикле нельзя использовать как механизм синхронизации или обязательную проверку каждой ошибки. Сам итератор не делает коллекцию безопасной для одновременной записи из разных потоков.
Проверьте пустой список, список без отрицательных чисел и список только из отрицательных. Затем отдельно, на новом списке, вызовите remove до next и дважды после одного next. Сопоставьте результат с последовательностью вызовов, а не только с текстом исключения.
Для простого удаления по условию рассмотрите также removeIf, а Iterator оставьте для случаев, когда логика обхода требует явного управления. Подобрать подход можно на практических занятиях по Java и обсудить с ментором по Java.