为何Iterator嵌套循环remove抛ConcurrentModificationException,单循环不抛?
为什么两段迭代器代码的行为差异?
Java集合的**快速失败(fail-fast)**机制是核心原因:集合内部维护了一个修改计数器modCount,每次通过非迭代器途径修改集合时,这个计数器会递增。而迭代器自身会保存一个expectedModCount,每次遍历都会校验这个值和集合的modCount是否一致,一旦不一致就抛出ConcurrentModificationException。
第二段代码无异常的原因
这段代码全程仅使用同一个迭代器完成遍历和删除操作:
Iterator<Integer> iterator = numbers.iterator(); while (iterator.hasNext()) { if (iterator.next() == 1) { iterator.remove(); // Doesn't throw exception } }
调用iterator.remove()时,迭代器会自动同步更新自身的expectedModCount,让它和集合的modCount保持一致,不会触发快速失败机制,因此不会抛出异常。
第一段代码抛出异常的原因
这段代码存在两个独立的迭代器,触发了快速失败:
Iterator<Integer> itr = ls.iterator(); for (Integer x : ls) { int count = 0; while(itr.hasNext()){ if (itr.next().equals(x)) { count++; if (count > 1) { itr.remove(); } } } }
- 你手动声明了
itr迭代器,同时增强for循环(for-each)底层也会创建一个全新的迭代器,这两个迭代器完全独立。 - 当你通过
itr.remove()修改集合时,集合的modCount会递增,但增强for循环的迭代器没有同步更新自己的expectedModCount。 - 等增强for循环进入下一次迭代时,它检测到
modCount和expectedModCount不匹配,就抛出了ConcurrentModificationException。
另外还有个次要问题:第一次while循环就会把itr遍历完毕,后续增强for循环进入while时,itr.hasNext()会直接返回false,内部逻辑不会执行,但这不是抛出异常的核心原因。
内容的提问来源于stack exchange,提问作者Sandeep T
相关产品推荐
相关产品推荐

