在arraylist遍历时直接调用remove()会抛出concurrentmodificationexception,安全删除方式有四种:①使用iterator的remove()方法;②使用listiterator反向遍历删除;③收集待删元素后批量调用removeall();④使用java 8+的removeif()。

在 ArrayList 遍历时直接调用 remove() 会抛出 ConcurrentModificationException,因为普通 for 循环或增强 for 循环(for-each)底层使用的是迭代器,而手动修改集合结构会触发 fail-fast 机制。要安全删除,必须使用支持边遍历边修改的机制。
使用 Iterator 的 remove() 方法
这是最常用、最推荐的方式。Iterator 提供了线程安全的 remove() 方法,它只能在调用 next() 之后立即调用,且每次只删一个元素。
示例:
List<string> list = new ArrayList(Arrays.asList("a", "b", "c", "b", "d"));
Iterator<string> it = list.iterator();
while (it.hasNext()) {
String s = it.next();
if ("b".equals(s)) {
it.remove(); // 安全删除
}
}
// 结果:["a", "c", "d"]
</string></string>
使用 ListIterator 反向遍历删除
如果需要从后往前删(比如避免索引偏移影响),可用 ListIterator,它支持双向遍历和 remove(),且反向操作更直观。
说明:
- 先用
list.listIterator(list.size())获取指向末尾的迭代器 - 用
hasPrevious()和previous()倒序访问 - 调用
remove()删除当前元素
收集待删元素,遍历结束后批量删除
适合条件复杂、需多次判断的场景。先用另一个集合暂存要删的元素,再调用 removeAll()。
Java开发手册规约集合,基于阿里巴巴Java开发手册(嵩山版)。 涵盖7大维度:编程规约、异常日志、单元测试、安全规约、MySQL数据库、工程结构、设计规约。 当用户需要:(1) 编写或审查Java代码 (2) 检查命名/代码规范 (3) 处理异常和日志 (4) 编写单元测试 (5) 安全编码 (6) 数据库设...
注意点:
- 确保待删集合类型与原集合兼容(如都是
String) -
removeAll()时间复杂度可能较高(取决于实现),小数据量无感,大数据量慎用 - 若原 list 允许重复,
removeAll()会删掉所有匹配项
示例:
List<string> list = new ArrayList(Arrays.asList("a", "b", "c", "b"));
List<string> toRemove = new ArrayList();
for (String s : list) {
if ("b".equals(s)) {
toRemove.add(s);
}
}
list.removeAll(toRemove); // 安全,不干扰遍历
</string></string>
使用 removeIf()(Java 8+)
最简洁的方式,内部已封装安全逻辑,基于 Iterator.remove() 实现。
示例:
list.removeIf(s -> "b".equals(s));
等价于手动用 Iterator 删除,但代码更清晰,语义更强。适用于单条件过滤。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










