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