Java遍历集合时安全删除元素需用Iterator.remove()、removeIf()、倒序for循环或CopyOnWriteArrayList;其中Iterator.remove()最标准,removeIf()最简洁,倒序遍历仅适用于List,CopyOnWriteArrayList适合读多写少的并发场景。

在 Java 中直接用 for-each 或普通 for 循环遍历集合时调用 collection.remove(),会触发 ConcurrentModificationException。这是因为迭代器检测到集合结构被意外修改(非迭代器自身 remove() 方法),从而抛出异常。要安全删除,关键在于**使用迭代器的 remove() 方法**,或改用线程安全/支持并发修改的集合类型。
用 Iterator 的 remove() 方法(最常用)
这是最标准、最推荐的方式。Iterator 的 remove() 是唯一被允许在遍历时安全删除元素的操作,它会同步更新内部状态,避免校验失败。
- 必须在调用
next()之后立即调用remove(),否则抛IllegalStateException - 每次只能删一个元素(即每调一次
next()后最多调一次remove()) - 示例:
用 removeIf() 方法(Java 8+,简洁推荐)
Collection.removeIf(Predicate) 内部封装了迭代逻辑,自动使用安全的迭代器删除,代码更清晰,适合条件删除。
Java开发手册规约集合,基于阿里巴巴Java开发手册(嵩山版)。 涵盖7大维度:编程规约、异常日志、单元测试、安全规约、MySQL数据库、工程结构、设计规约。 当用户需要:(1) 编写或审查Java代码 (2) 检查命名/代码规范 (3) 处理异常和日志 (4) 编写单元测试 (5) 安全编码 (6) 数据库设...
- 底层仍基于
Iterator.remove(),语义明确且不易出错 - 一行解决,可读性高,例如:
list.removeIf(s -> "b".equals(s)); - 注意:该方法是
Collection接口默认方法,所有标准集合(ArrayList、LinkedList、HashSet等)都支持
用 for 循环倒序遍历(仅适用于 List)
对 List 类型,可改用索引从后往前删。因为删除末尾元素不会影响前面未遍历元素的下标,避免越界和漏删。
立即学习“Java免费学习笔记(深入)”;
- 只适用于
List(如ArrayList、LinkedList),不适用于Set或Map - 示例:
for (int i = list.size() - 1; i >= 0; i--) {
if ("b".equals(list.get(i))) {
list.remove(i); // ✅ 安全(因倒序)
}
}
用 CopyOnWriteArrayList(适合读多写少的并发场景)
如果在多线程环境下频繁遍历且偶尔删除,可考虑 CopyOnWriteArrayList。它的迭代器基于快照,遍历时修改原集合不影响当前迭代,自然不抛 ConcurrentModificationException。
- 优点:线程安全,遍历时可任意修改
- 缺点:写操作(add/remove)开销大(复制整个数组),内存占用高,不适合高频写场景
- 仅建议用于“读远大于写”且需遍历中修改的并发场合

















