java中for-each循环直接调用remove()会抛concurrentmodificationexception,安全删除需用iterator.remove()、removeif()或反向for循环;不推荐先收集再批量删除。

Java 中用 for-each 循环(增强型 for 循环)直接调用 collection.remove() 删除元素会抛出 ConcurrentModificationException,因为 for-each 底层依赖迭代器,而集合结构被修改后迭代器会快速失败(fail-fast)。要安全删除,不能在 for-each 中直接删,得换用支持边遍历边修改的机制。
使用 Iterator 的 remove() 方法
这是最常用、最推荐的方式。Iterator 的 remove() 是唯一被设计为在遍历时安全删除元素的方法,它会同步更新内部状态,避免异常。
- 先获取集合的迭代器(
iterator()),再用 while 循环配合hasNext()和next() - 调用
it.remove()删除当前元素(必须在next()之后调用,否则抛IllegalStateException) - 示例:删除所有偶数
List<integer> list = new ArrayList(Arrays.asList(1, 2, 3, 4, 5));
Iterator<integer> it = list.iterator();
while (it.hasNext()) {
Integer num = it.next();
if (num % 2 == 0) {
it.remove(); // ✅ 安全
}
}</integer></integer>使用 removeIf()(Java 8+)
对 Collection 接口的实现类(如 ArrayList、HashSet),可直接调用 removeIf(Predicate),内部已封装了安全的迭代逻辑。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 语义清晰,一行代码表达“删除满足条件的元素”
- 底层仍基于迭代器,但由 JDK 保证线程安全(单线程下)和结构一致性
- 示例:同上,删除偶数
list.removeIf(num -> num % 2 == 0); // ✅ 简洁安全
反向 for 循环(仅适用于 List)
如果操作的是 List(如 ArrayList),可用传统 for 循环从后往前删。因为删除索引 i 的元素后,i 后面的元素会前移,但前面的索引不受影响,反向遍历可避免漏删或越界。
- 注意:只适用于支持随机访问的 List,不适用于 Set 或 Queue
- 需手动维护索引,不如 Iterator 或 removeIf 直观,但有时性能略优(无迭代器对象开销)
- 示例:
for (int i = list.size() - 1; i >= 0; i--) {
if (list.get(i) % 2 == 0) {
list.remove(i); // ✅ 反向删不会跳过元素
}
}不推荐的做法:收集待删元素再批量删除
先遍历一次,把要删的元素存进另一个集合,再调用 removeAll()。虽然不会报异常,但有明显缺点:
- 需要额外空间存储待删项(尤其大数据量时内存开销大)
- 若集合中存在重复元素,
removeAll()会删掉所有匹配项,可能不符合预期(比如只想删第一个) - 两次遍历,时间复杂度翻倍
- 不是真正“遍历时删除”,而是分两步,逻辑割裂
除非有特殊需求(如需记录哪些被删),否则应优先选 Iterator 或 removeIf。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










