List 抛出 ConcurrentModificationException 但 set 不抛出 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 类中,相同的逻辑由 set family 执行.
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,但没有任何 ConcurrentModificationException 以防万一set
家族
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
的演示.
这篇关于List 抛出 ConcurrentModificationException 但 set 不抛出 ConcurrentModificationException?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!