📅  最后修改于: 2023-12-03 15:37:36.419000             🧑  作者: Mango
在Java中,迭代器是一种方便和安全访问集合元素的方法。然而,在使用迭代器遍历集合时,有时会出现ConcurrentModificationException的异常,本文将介绍该异常的产生原因和解决方法。
在使用迭代器遍历集合时,若在遍历时修改了集合的结构(比如添加或删除元素),就会导致ConcurrentModificationException异常的抛出。
例如下述代码片段(Java 8):
List<Integer> list = new ArrayList<>(Arrays.asList(1, 2, 3, 4, 5));
for (Integer i : list) {
if (i == 3) {
list.remove(i);
}
}
执行该代码时,就会出现ConcurrentModificationException异常。
当调用集合的iterator()方法时,在迭代器被创建时,会将集合的modCount值保存在迭代器的expectedModCount变量中。
在每次使用迭代器遍历集合时,都会比较expectedModCount与集合的modCount是否相等,如果不相等,就说明集合已经被修改,抛出ConcurrentModificationException异常。
而在上述代码中,我们在遍历时直接修改了集合,导致了异常的抛出。
使用迭代器的remove()方法:在遍历集合时,调用迭代器的remove()方法,而不是直接调用集合的remove()方法。
例如:
List<Integer> list = new ArrayList<>(Arrays.asList(1, 2, 3, 4, 5));
for (Iterator<Integer> iterator = list.iterator(); iterator.hasNext();) {
Integer i = iterator.next();
if (i == 3) {
iterator.remove();
}
}
在以上代码中,我们使用了迭代器的remove()方法,而没有直接修改集合,就避免了ConcurrentModificationException异常的抛出。
将集合复制到一个临时集合中:在遍历集合时,将集合复制到一个临时的集合中进行遍历,修改集合时也只在临时集合中进行,最后再将临时集合中的元素复制回原集合中。
例如:
List<Integer> list = new ArrayList<>(Arrays.asList(1, 2, 3, 4, 5));
List<Integer> tempList = new ArrayList<>(list);
for (Integer i : tempList) {
if (i == 3) {
list.remove(i);
}
}
在以上代码中,我们将原集合复制到了临时集合tempList中进行遍历和修改,最后再将tempList中的元素复制回原集合list中。
以上就是在Java使用迭代器时出现ConcurrentModificationException异常的解决方法。我们应该在代码中遵守集合与迭代器的规范,以避免这一问题的发生。