只能用Iterator.remove(),因为集合的modCount与迭代器的expectedModCount需保持一致,直接调集合remove()会破坏一致性而抛ConcurrentModificationException,而Iterator.remove()会同步更新expectedModCount。

Java 集合遍历时,**直接调用集合自身的 remove() 方法会导致 ConcurrentModificationException(并发修改异常)**,因为普通 for 循环或增强 for 循环底层都依赖迭代器,但未走迭代器的删除逻辑。而 Iterator 的 remove() 方法是唯一被设计为在遍历中安全删除元素的机制。
为什么只能用 Iterator.remove()?
ArrayList、LinkedList 等集合内部维护一个 modCount(修改计数器),每次结构修改(如 add/remove)都会递增。Iterator 在创建时会记录当时的 expectedModCount;每次调用 next() 前都会校验两者是否一致。若你绕过 Iterator 直接调集合的 remove(),modCount 变了但 expectedModCount 没变,下一次 next() 就抛异常。
而 Iterator.remove() 会在删除后同步更新 expectedModCount,保持一致,因此安全。
正确写法:先 next(),再 remove()
必须严格遵守「调用 next() 获取元素 → 判断条件 → 调用 remove()」的顺序。不能在没调 next() 时调 remove(),也不能连续调两次 remove()(会抛 IllegalStateException)。
立即学习“Java免费学习笔记(深入)”;
- ✅ 正确示例(删除所有偶数):
Iterator<Integer> it = list.iterator();
while (it.hasNext()) {
Integer num = it.next(); // 必须先 next()
if (num % 2 == 0) {
it.remove(); // 再 remove()
}
}
增强 for 循环不能删,但可改用 while + iterator
增强 for(for-each)本质是语法糖,底层仍用 Iterator,但它隐藏了迭代器对象,**无法访问 remove() 方法**,所以以下写法会编译失败或运行时报错:
for (Integer x : list) {
if (x % 2 == 0) {
list.remove(x); // ❌ 运行时报 ConcurrentModificationException
}
}
想保持简洁逻辑?直接换成显式 Iterator 的 while 循环,语义清晰且安全。
注意 remove() 的作用范围和限制
-
it.remove()删除的是上一次next()返回的那个元素,不是当前判断的“下一个”元素 - 一个
next()后最多调一次remove();重复调会抛IllegalStateException - 不支持添加元素(
add()不在 Iterator 接口中);如需边遍历边添加,考虑收集待添加元素,遍历完再批量 add - 对
CopyOnWriteArrayList等线程安全集合,虽可用普通 remove,但 Iterator.remove() 依然推荐,语义统一、行为确定


















