И вот почему:
Как говорится в Javadoc:
Итераторы, возвращаемые итераторами этого класса и listIterator
методы работают быстро: если список структурно изменен
время после создания итератора, любым способом, кроме как через
собственные методы удаления или добавления итератора, итератор выдаст
ConcurrentModificationException.
Эта проверка выполняется в методе next()
итератора (как вы можете видеть по трассировке стека). Но мы достигнем метода next()
только в том случае, если hasNext()
доставил true, то есть то, что вызывается для каждого, чтобы проверить, встречается ли граница. В вашем методе удаления, когда hasNext()
проверяет, нужно ли ему возвращать другой элемент, он увидит, что он возвратил два элемента, и теперь после удаления одного элемента список содержит только два элемента. Так что все хорошо, и мы сделали с итерацией. Проверка на одновременные изменения не происходит, поскольку это делается в методе next()
, который никогда не вызывается.
Далее мы перейдем ко второму циклу. После того, как мы удалим второе число, метод hasNext снова проверит, может ли вернуть больше значений. Он уже вернул два значения, но теперь список содержит только одно значение. Но код здесь:
public boolean hasNext() {
return cursor != size();
}
1! = 2, поэтому мы переходим к методу next()
, который теперь понимает, что кто-то возился со списком, и вызывает исключение.
Надеюсь, это прояснит ваш вопрос.
Краткое описание
List.remove()
не будет выбрасывать ConcurrentModificationException
при удалении второго последнего элемента из списка.