问题分析
java.util.ConcurrentModificationException
异常通常在尝试对集合(如 ArrayList
、HashSet
等)进行迭代操作时,同时对该集合的结构进行修改(如添加、删除元素)时抛出。这个异常是 Java 集合框架的一部分,旨在提醒开发者在并发修改集合时可能出现的问题。
报错原因
当使用迭代器(如 Iterator
、ListIterator
、Enumeration
等)遍历集合时,如果同时直接通过集合的方法(如 add
、remove
等)修改了集合的大小或结构,迭代器就会抛出 ConcurrentModificationException
异常。
解决思路
- 使用迭代器的修改方法:如果需要在迭代过程中修改集合,应使用迭代器提供的
add
、remove
方法,而不是集合的对应方法。 - 使用并发集合:如果确实需要在多线程环境下修改集合,可以考虑使用 Java 提供的并发集合类,如
CopyOnWriteArrayList
、ConcurrentHashMap
等。 - 复制集合:如果不需要在迭代过程中实时反映集合的修改,可以先复制集合,然后在迭代过程中修改复制的集合。
解决方法
1. 使用迭代器的修改方法
Iterator<String> iterator = list.iterator();
while (iterator.hasNext()) {
String item = iterator.next();
if (someConditionToDelete(item)) {
iterator.remove(); // 使用迭代器的 remove 方法
}
}
2. 使用并发集合
下滑查看解决方法
如果你正在处理多线程环境,并需要实时反映集合的修改,可以考虑使用并发集合:
List<String> concurrentList = new CopyOnWriteArrayList<>();
// 在多线程环境下,可以直接使用 concurrentList.add(), concurrentList.remove() 等方法
注意:CopyOnWriteArrayList
在修改时会复制底层数组,因此适用于读多写少的场景。
3. 复制集合
如果你不需要在迭代过程中实时反映集合的修改,可以先复制集合:
List<String> originalList = ...; // 原始列表
List<String> tempList = new ArrayList<>(originalList); // 复制列表
for (String item : tempList) {
if (someConditionToDelete(item)) {
originalList.remove(item); // 修改原始列表
}
}
注意:这种方法只适用于在迭代过程中不依赖于集合结构变化的场景,因为你在迭代 tempList
的同时修改了 originalList
。如果 someConditionToDelete
依赖于 originalList
的当前状态,这种方法可能会导致问题。