列表引发ConcurrentModificationException,但集合不会引发ConcurrentModificationException? [英] List throws ConcurrentModificationException but set does not throws ConcurrentModificationException?
问题描述
我下面有两个java类
I have below two java class
import java.util.*;
public class ArrayListTest032 {
public static void main(String[] ar) {
List<String> list = new ArrayList<String>();
list.add("core java");
list.add("php");
list.add("j2ee");
list.add("struts");
list.add("hibernate");
Iterator<String> itr = list.iterator();
while (itr.hasNext()) {
System.out.println(itr.next());
}
list.remove("php");
while (itr.hasNext()) {
System.out.println(itr.next());
}
}
}
当我在上面的代码上运行时,我会得到下面的输出.
When I run above code I get below output.
core java
php
j2ee
struts
hibernate
Exception in thread "main" java.util.ConcurrentModificationException
at java.util.AbstractList$Itr.checkForComodification(AbstractList.java:372)
at java.util.AbstractList$Itr.next(AbstractList.java:343)
at ArrayListTest032.main(ArrayListTest032.java:20)
在迭代时我正在修改列表,这是可以预期的.但是在下面的java类中,集合家族执行相同的逻辑.
Which is expected as I am modifying the list while iterating. But in below java class same logic is executed by set family.
import java.util.*;
public class HashSetTest021 {
public static void main(String[] ar) {
Set<String> set = new HashSet<String>();
set.add("core java");
set.add("php");
set.add("j2ee");
set.add("struts");
set.add("hibernate");
Iterator<String> itr = set.iterator();
while (itr.hasNext()) {
System.out.println(itr.next());
}
set.remove("php");
while (itr.hasNext()) {
System.out.println(itr.next());
}
}
}
输出是.
hibernate
core java
j2ee
php
struts
没有任何 ConcurrentModificationException .
我只想知道为什么在list
系列的情况下相同的代码会抛出 ConcurrentModificationException ,但是对于set
系列的情况却没有任何 ConcurrentModificationException
I just want to know why same piece of code throws ConcurrentModificationException in case of list
family, but there is no any ConcurrentModificationException in case of set
family
推荐答案
这是实现上的区别:数组列表返回的迭代器即使位于末尾也可以检测到并发的修改,因为它检查了长度;另一方面,HashSet
,TreeSet
和LinkedList
的迭代器不会检测到这种情况,因为它们在检查并发修改之前会检查其位于末尾.该文档允许迭代器不要进行并发修改,因此这两种方法都是有效的.
This is a difference in the implementation: the iterator returned by the array list detects concurrent modifications even when it is positioned at the end, because it checks the length; iterators of the HashSet
, TreeSet
and LinkedList
, on the other hand, do not detect this condition, because they check for being positioned at the end before checking for concurrent modification. The documentation allows iterators not to throw on concurrent modifications, so both approaches are valid.
-
TreeSet
的演示. -
LinkedList
的演示.
这篇关于列表引发ConcurrentModificationException,但集合不会引发ConcurrentModificationException?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!