必须用Iterator.remove()而非Collection.remove(),因集合的fail-fast机制通过modCount校验确保遍历安全;Iterator.remove()同步更新计数器,而直接remove会触发ConcurrentModificationException。

遍历集合时删除元素,必须用 Iterator.remove(),不能直接调用 Collection.remove(),否则会抛出 ConcurrentModificationException。
为什么不能在遍历时直接调用 Collection.remove()?
Java 中的大多数集合(如 ArrayList、HashSet)采用“快速失败”(fail-fast)机制。遍历时,迭代器会维护一个内部修改计数器(modCount),与集合自身的修改计数(expectedModCount)比对。一旦集合被外部方法(如 list.remove(obj))修改,计数器不一致,下一次调用 next() 或 hasNext() 就会立即抛异常。
这不是线程安全问题,即使单线程也会触发。
Iterator.remove() 是唯一安全的遍历中删除方式
Iterator.remove() 是迭代器自己提供的删除方法,它会在删除后同步更新内部计数器,保持一致性。该方法只能在调用过 next() 之后使用一次,否则抛 IllegalStateException。
立即学习“Java免费学习笔记(深入)”;
- 必须先调用
iterator.next()获取当前元素 - 再调用
iterator.remove()删除刚取到的元素 - 不能连续调两次
remove(),也不能在next()前调用
替代方案:倒序遍历(仅适用于 List)
对于 ArrayList 等支持随机访问的 List,可改用传统 for 循环,从后往前删:
for (int i = list.size() - 1; i >= 0; i--) {<br> if (shouldRemove(list.get(i))) {<br> list.remove(i); // 安全,因为索引不会因后续元素前移而错位<br> }<br>}
注意:正向 for + remove() 会导致漏删(索引跳变),必须倒序或每次删完 i-- 补偿。
批量删除推荐用 removeIf()(Java 8+)
如果只是按条件过滤删除,优先用 Collection.removeIf(Predicate):
list.removeIf(x -> x == null || x.isEmpty());
它内部封装了安全的迭代逻辑,语义清晰、代码简洁,且性能通常优于手动遍历。


















