Iterator.remove() 能避免 ConcurrentModificationException 是因为它在删除元素的同时同步更新 expectedModCount 与 modCount;而直接调用 list.remove() 只修改 modCount,导致迭代器校验失败。

因为 Iterator.remove() 会同步更新迭代器内部的 expectedModCount,让它始终与集合的 modCount 保持一致,从而绕过 fail-fast 的校验。
fail-fast 是靠两个计数器“对账”来工作的
Java 集合(如 ArrayList)内部维护一个 modCount 字段,记录结构修改次数(增、删、清空都会+1)。迭代器创建时,会把当时的 modCount 值存为自己的 expectedModCount。之后每次调用 next() 前,都会检查两者是否相等——不等就抛 ConcurrentModificationException。
直接调用 list.remove() 为什么失败
它只改了 modCount,但没通知迭代器,导致 expectedModCount 滞后。下一次 next() 就会发现“账对不上”,立刻报错。
Iterator.remove() 的关键动作
- 必须在
next()之后调用,此时lastRet已记录被遍历元素的索引 - 内部真正执行
ArrayList.this.remove(lastRet) - 紧接着执行
expectedModCount = modCount,完成同步 - 重置
lastRet = -1,防止重复调用
它不是“延迟删除”,而是“即时同步”
网上有说法称“标记删除、迭代结束才真正移除”,这是误解。实际是:调用 it.remove() 的那一刻,元素就被从底层数组中删掉了,同时 modCount 和 expectedModCount 也被立即对齐。整个过程原子且闭环,不给 fail-fast 触发机会。
立即学习“Java免费学习笔记(深入)”;


















