在Java中遍历ArrayList并安全删除元素,应避免普通或增强for循环直接调用remove(),推荐使用Iterator的remove()方法、倒序for循环、收集后批量删除或Java 8+的removeIf()。

在 Java 中遍历 ArrayList 并安全删除元素,关键在于**避免使用普通 for 循环或增强 for 循环直接调用 remove() 方法**,否则会抛出 ConcurrentModificationException 或导致漏删、越界等错误。正确方式是使用迭代器的 remove() 方法,或改用支持安全删除的遍历逻辑。
用 Iterator 的 remove() 方法(最推荐)
这是官方推荐的安全删除方式。迭代器的 remove() 是唯一允许在遍历中修改集合的操作,它会同步更新内部状态,避免并发修改异常。
- 必须先调用
next()获取元素,才能调用remove() - 每次
remove()只能调用一次,重复调用会抛IllegalStateException - 不能和集合自身的
remove()混用(如list.remove(obj))
Iterator<String> it = list.iterator();
while (it.hasNext()) {
String s = it.next();
if ("target".equals(s)) {
it.remove(); // ✅ 安全删除
}
}倒序 for 循环(适合按索引条件删除)
从后往前遍历,删除元素不会影响尚未访问的前面元素的索引,因此可安全使用 remove(int index)。
- 适用于根据索引位置或下标规律(如偶数位、末尾几个)删除
- 不依赖元素内容判断时更直观;若需按值删除,仍要配合
indexOf()或遍历查找,效率略低
for (int i = list.size() - 1; i >= 0; i--) {
if ("target".equals(list.get(i))) {
list.remove(i); // ✅ 索引稳定,安全
}
}收集待删元素,遍历结束后批量移除
先遍历一次记录要删的元素(或其索引),再统一调用 removeAll() 或循环删除。适合删除条件复杂、或需多次判断的场景。
立即学习“Java免费学习笔记(深入)”;
- 注意:用
removeAll(Collection)时,传入的集合不能是原 list 的子集(如subList),否则可能出错 - 若用索引列表,删除时仍建议倒序,或改用
removeAll()配合stream().map(...).collect()
List<String> toRemove = new ArrayList<>();
for (String s : list) {
if (shouldRemove(s)) {
toRemove.add(s);
}
}
list.removeAll(toRemove); // ✅ 安全,但注意 equals 实现Java 8+ 的 removeIf()(简洁且安全)
一行代码搞定,底层基于迭代器实现,线程安全仅限单线程场景(本身不是线程安全方法,但无并发修改问题)。
- 语义清晰,函数式风格,推荐用于简单条件删除
- 内部已处理迭代与删除的协同,无需手动管理迭代器
list.removeIf(s -> "target".equals(s)); // ✅ 简洁安全


















