应使用iterator的remove()方法、removeif()或倒序for循环删除arraylist元素;因普通/增强for循环中调用list.remove()会触发fail-fast机制抛concurrentmodificationexception。

在 Java 中,使用 ArrayList 的普通 for 循环或增强 for 循环(for-each)直接调用 list.remove() 删除元素,会导致 ConcurrentModificationException 异常。这是因为 ArrayList 的迭代器是“快速失败”(fail-fast)的,当检测到结构被意外修改(如外部 remove),就会抛出异常。
用 Iterator 的 remove() 方法安全删除
这是最标准、最推荐的方式:获取迭代器后,**只能通过该迭代器自身的 remove() 方法删除当前元素**,不能调用集合本身的 remove()。
- 调用
iterator.next()后,才能调用iterator.remove() - 每个
next()最多对应一次remove(),重复调用会抛IllegalStateException - 该操作是线程不安全的,但单线程下完全可靠
Iterator<string> it = list.iterator();
while (it.hasNext()) {
String s = it.next();
if (s.startsWith("A")) {
it.remove(); // ✅ 正确:用迭代器自己的 remove
}
}</string>
使用 removeIf()(Java 8+,更简洁)
如果只是根据条件批量删除,Collection.removeIf(Predicate) 是语义清晰、内部已封装好迭代逻辑的安全方式。
- 底层仍使用迭代器,自动处理并发修改检查
- 代码更短,意图更明确,无需手动管理迭代器
- 适用于大多数“满足条件就删”的场景
list.removeIf(s -> s.startsWith("A")); // ✅ 简洁且安全
倒序 for 循环(适用于索引删除)
如果必须用索引操作,可改用从后往前的普通 for 循环。这样删除元素不会影响尚未访问的前面元素的索引。
- 避免了迭代器机制,绕过 fail-fast 检查
- 适合需要根据索引做复杂判断(如比较相邻元素)的场景
- 注意:不能用正向 for 循环 + remove,否则会跳过下一个元素
for (int i = list.size() - 1; i >= 0; i--) {
if (list.get(i).startsWith("A")) {
list.remove(i); // ✅ 安全:倒序删除不影响前面索引
}
}
不推荐的做法(容易出错)
以下方式看似可行,实则隐患明显:
- 增强 for 循环中调用
list.remove()→ 必抛ConcurrentModificationException - 正向 for 循环中删除后未调整索引(如 i--)→ 会漏删相邻元素
- 先收集待删元素再批量 removeAll() → 多一次遍历,内存开销略大,且需注意 equals/hashCode 正确性
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











