Трудно дать диагностику для проблемы, когда показанный код явно не тот код, который породил исключение, поскольку он даже не компилируется. Метод remove
для Iterator
не принимает аргументов, а метод set
определен для ListIterator
, но ваш код объявляет переменную i
только как Iterator
.
ИсправленоВерсия
private void myMethod(ArrayList<Integer> input) {
ListIterator<Integer> i = input.listIterator();
while (i.hasNext()) {
Integer in = i.next();
if (in < 10)
i.remove();
else
i.set(in*in);
}
}
будет работать без проблем. Ответ на ваш общий вопрос заключается в том, что каждая модификация делает недействительными все существующие итераторы, кроме того, который использовался для модификации, когда вы использовали итератор для модификации, а не интерфейс коллекции напрямую.
Но в вашем кодеесть только один итератор, который создается и используется только для этой операции. До тех пор, пока не будет перекрывающегося использования итераторов для одной и той же коллекции, нет проблем с аннулированием. Итераторы, существующие из предыдущих операций, все равно отменяются, а итераторы, используемые в последующих операциях, еще не существуют.
Тем не менее, вместо этого проще использовать
private void myMethod(ArrayList<Integer> input) {
input.removeIf(in -> in < 10);
input.replaceAll(in -> in*in);
}
. В отличие от исходного кода, он выполняет две итерации, но, как объяснено в , этот ответ , removeIf
будет на самом деле быстрее, чем удаление на основе итераторов в тех случаях, когда производительность действительно имеет значение.
НоИ все же проблема сохраняется. Показанный код не может вызвать ConcurrentModificationException
, поэтому ваша настоящая проблема где-то еще и может присутствовать, независимо от того, как был реализован этот метод.