唯一可靠方式是使用 iterator.remove(),因其同步更新 expectedmodcount 以维持 fail-fast 一致性;必须先 next() 再 remove(),否则抛 concurrentmodificationexception 或 illegalstateexception。

Java 中在遍历集合时安全删除元素,唯一可靠的方式是使用 Iterator.remove(),且必须严格遵循调用顺序:先调用 next() 获取元素,再立即调用 remove()。其他任何方式(如增强 for 循环中调 list.remove()、普通 for 循环中按索引删)都会导致异常或漏删。
为什么只能用 Iterator.remove()?
Java 集合(如 ArrayList、HashSet)采用 fail-fast 机制:迭代器创建时会记录集合的修改计数器 modCount(存为 expectedModCount)。每次调 next() 前都会校验两者是否一致。直接调集合的 remove() 会更新 modCount,但不通知迭代器,校验失败即抛 ConcurrentModificationException。
而 Iterator.remove() 是特例——它由迭代器自己执行删除,并同步更新 expectedModCount,维持一致性。
正确写法:三步不能错
- 显式获取迭代器:
Iterator<string> it = list.iterator();</string> - 用
while(it.hasNext())控制循环,每次进循环体前必须先调it.next() - 仅在刚拿到当前元素后、且尚未再次调
next()前,调it.remove()(每调一次next()最多调一次remove())
示例:
List
Iterator
while (it.hasNext()) {
String s = it.next();
if ("b".equals(s)) {
it.remove(); // ✅ 安全,删除的是上一次 next() 返回的 "b"
}
}
常见错误写法
- 增强 for 循环里调集合 remove:
for (String s : list) { if (s.isEmpty()) list.remove(s); }→ 编译通过但运行时抛ConcurrentModificationException - 未调
next()就remove()→ 抛IllegalStateException - 连续两次
it.remove()(中间没next())→ 同样抛IllegalStateException - 正向 for 循环中用
list.remove(i)→ 不抛异常,但因元素前移导致跳过下一个元素
更简洁的替代方案(Java 8+)
如果只是按条件过滤,推荐用 Collection.removeIf(Predicate):
list.removeIf(s -> s.length() > 5); // ✅ 底层仍用 Iterator.remove(),语义清晰、代码短
注意:removeIf() 不适合需要在删除前记录日志、统计、或依赖复杂状态判断的场景;它也不支持获取被删元素本身。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











