在Java中遍历集合时删除元素需避免ConcurrentModificationException,安全方式包括:①用Iterator.remove();②Java 8+的removeIf();③List倒序for循环;④先收集待删元素再统一removeAll()。

在 Java 中,直接在 for-each 循环或普通 for 循环中调用集合的 remove() 方法删除元素,会触发 ConcurrentModificationException(并发修改异常)。这是因为迭代器检测到集合结构被意外修改,而它本身并未参与该修改。安全删除的关键是**使用迭代器自身的 remove() 方法**,或改用支持安全删除的替代方案。
用 Iterator 的 remove() 安全删除
这是最经典、最通用的方式。Iterator 的 remove() 是唯一被允许在遍历时删除当前元素的方法,它会同步更新内部状态,避免异常。
- 必须先调用
next()获取元素,再调用remove();不能连续调用两次remove() - 不能在一次
next()后多次调用remove(),否则抛IllegalStateException - 适用于
ArrayList、LinkedList、HashSet等绝大多数集合
示例:
分析 Java Spring Boot 后端 Controller 代码,自动生成 Markdown 格式的接口文档。当用户说“生成 Java 接口文档”、“生成 API 文档”、“从 Spring 代码生成文档”时触发。
Iterator<string> it = list.iterator();
while (it.hasNext()) {
String item = it.next();
if ("toRemove".equals(item)) {
it.remove(); // ✅ 安全
}
}</string>用 removeIf() 批量条件删除(Java 8+)
Collection.removeIf(Predicate) 内部使用迭代器安全实现,语法简洁,适合按条件批量删除。
- 底层仍基于迭代器,线程不安全,但单线程下完全安全
- 不能在 lambda 中修改集合本身(比如再调
remove()),否则可能出错 - 返回
boolean表示是否有元素被删除
示例:
list.removeIf(item -> item.startsWith("temp")); // ✅ 删除所有以 "temp" 开头的元素倒序 for 循环删除(仅限 List)
对 ArrayList 或 LinkedList 等有序 List,可从末尾向前遍历并用索引删除。因为删除后索引变化不影响尚未访问的前面元素。
- 只适用于实现了
RandomAccess或明确支持索引删除的 List - 注意:删除后
size()实时变化,循环条件要用i >= 0,且每次删完不需i--(因为下一个要删的元素已自动前移)
示例:
for (int i = list.size() - 1; i >= 0; i--) {
if ("obsolete".equals(list.get(i))) {
list.remove(i); // ✅ 安全(索引递减方向)
}
}收集待删元素,遍历结束后统一删除
如果逻辑复杂(如需跨元素判断、或删除依赖外部状态),可先用临时集合记录待删项,再调用 removeAll()。
- 简单直观,适合多条件组合判断场景
- 注意:
removeAll()时间复杂度取决于集合类型(如 HashSet 是 O(n),ArrayList 是 O(n×m)) - 确保待删集合与原集合元素可正确比较(重写
equals()和hashCode())
示例:
List<string> toRemove = new ArrayList();
for (String item : list) {
if (shouldRemove(item)) {
toRemove.add(item);
}
}
list.removeAll(toRemove); // ✅ 安全</string>Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










