在 java 中遍历集合时直接修改集合会抛出 concurrentmodificationexception,正确的做法是使用迭代器提供的 remove() 方法安全删除元素,或者使用 copyonwritearraylist 等线程安全的集合类。对于非并发场景,也可以先收集待删除的元素再统一处理,避免在遍历过程中改变集合结构。

Iterator.remove() 如何安全删除元素
使用 Iterator.remove() 可以在遍历过程中安全地移除当前元素,这是最标准的处理方式。该方法由迭代器内部维护状态,不会触发快速失败机制。示例中演示了如何过滤掉列表中的偶数,保留奇数。

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class SafeRemoveExample {
public static void main(String[] args) {
List<integer> numbers = new ArrayList(List.of(1, 2, 3, 4, 5));
Iterator<integer> iterator = numbers.iterator();
while (iterator.hasNext()) {
Integer num = iterator.next();
if (num % 2 == 0) {
iterator.remove(); // 安全删除
}
}
System.out.println(numbers); // [1, 3, 5]
}
}</integer></integer>
为什么直接调用 List.remove() 会失败
如果在增强 for 循环或普通 while 循环中直接调用集合的 remove() 方法,会破坏迭代器的预期结构,导致 ConcurrentModificationException。这是因为迭代器在创建时记录了集合的结构修改次数(modCount),每次调用 next() 时会检查该值是否变化。直接修改集合会更新 modCount,从而触发异常。

import java.util.ArrayList;
import java.util.List;
public class UnsafeRemoveExample {
public static void main(String[] args) {
List<string> list = new ArrayList(List.of("A", "B", "C"));
for (String item : list) {
if (item.equals("B")) {
list.remove(item); // 抛出 ConcurrentModificationException
}
}
}
}</string>
基于 CopyOnWriteArrayList 的并发修改策略
在高并发场景下,可以使用 CopyOnWriteArrayList 替代普通 ArrayList。该类在每次修改时都会复制底层数组,因此遍历使用的是快照,不会受到后续修改的影响。虽然内存开销较大,但读多写少的场景下性能优异且无需同步锁。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











