跳转到主内容
新派编程网 - 新潮编程理念,全新技术课堂!

在Java中如何安全地遍历List集合_Java集合遍历方式解析

遍历List时不能直接调用list.remove(),因快速失败机制下modCount不一致会抛ConcurrentModificationException;安全做法是用Iterator.remove()、removeIf()或倒序for循环。 为什么不能在遍历List时直接调用
remove()
直接用
for-each
或
Iterator.next()
遍历时调用
list.remove(obj)
会抛
ConcurrentModificationException
。这是因为
ArrayList
和
LinkedList
的迭代器是“快速失败”(fail-fast)的,内部维护
modCount
计数器,而
list.remove()
会修改该值,但迭代器没同步感知。 常见错误写法:
for (String s : list) { if (s.startsWith("a")) { list.remove(s); // ❌ 抛异常 } }
想边遍历边删元素,必须用
Iterator.remove()
,它是唯一被允许的删除方式
removeIf()
是Java 8+推荐替代方案,内部已做安全封装 用普通
for
倒序遍历(
i = size-1; i >= 0; i--
)也可行,但逻辑易错,不推荐用于复杂条件 用
Iterator.remove()
安全删除符合条件的元素 这是最通用、兼容所有
List
实现的安全方式,适用于Java 5+。 关键点: 立即学习 “ Java免费学习笔记(深入) ”; 必须调用
iterator.remove()
,不是
list.remove()
每次只能在
next()
之后调用一次
remove()
,否则抛
IllegalStateException
不支持并发修改——同一
List
对象不能在另一个线程里同时增删 示例:
Iterator it = list.iterator(); while (it.hasNext()) { String s = it.next(); if (s.length() == 0 || s.equals("null")) { it.remove(); // ✅ 安全 } }
Java 8+优先用
removeIf()
代替手写循环
removeIf(Predicate)
语义清晰、代码简洁,且底层自动使用
Iterator.remove()
,无需手动管理迭代器。 Eclipse导入Android或其他的JAVA项目的正确方法 WORD版 本文档主要讲述的是Eclipse导入Android或其他的JAVA项目的正确方法;希望本文档会给有需要的朋友带来帮助;感兴趣的朋友可以过来看看 下载 注意: 仅适用于
ArrayList
、
LinkedList
等标准实现;自定义
List
需确保重写了该方法 性能上与手写
Iterator
基本一致,JVM会内联优化 不能在
removeIf
的
Predicate
中修改原集合,否则行为未定义 示例:
list.removeIf(s -> s == null || s.trim().isEmpty());
多线程环境下遍历List必须用线程安全包装 即使用了
Iterator.remove()
或
removeIf()
,如果其他线程也在修改同一个
List
,依然会出错。 可行方案: 用
Collections.synchronizedList(new ArrayList())
,但注意:迭代仍需手动同步
list
对象 改用
CopyOnWriteArrayList
,适合读多写少场景;它的
iterator()
返回快照,遍历时允许其他线程修改,但
removeIf()
会加锁,且内存开销大 更稳妥的做法是:遍历前复制一份(
new ArrayList(original)
),在副本上操作 容易忽略的一点:同步块必须包裹整个遍历过程,不只是
remove()
调用。

相关文章