3
从TreeSet
(一SortedSet
)在Java中8:SortedSet :: removeAll(headSet)失败,但从headSet派生另一个集合成功。为什么?
- 我称之为
::headSet
方法在排序集合的前面,以获得对象的SortedSet
。 - 我打电话给
::removeAll
删除那些最前面的对象。
BAM,抛出一个ConcurrentModificationException
。
然而,如果我从headSet制作另一个SortedSet并将派生集合传递给::removeAll
,没有问题。
为什么?
使用Java 8更新的演示代码45.启用行//sortedSet.removeAll(headSet);
以查看引发的异常。
String cockatiel = "Cockatiel";
SortedSet sortedSet = new TreeSet<String>();
sortedSet.add("Dog");
sortedSet.add("Cat");
sortedSet.add("Bird");
sortedSet.add("Elephant");
sortedSet.add(cockatiel); // Passing var rather than literal.
sortedSet.add("Guppy");
System.out.println("Before: " + sortedSet);
// Direct way. FAIL
SortedSet<String> headSet = sortedSet.headSet(cockatiel);
System.out.println("headSet: " + headSet);
//sortedSet.removeAll(headSet); // Fails. Throws java.util.ConcurrentModificationException.
// Derived way. PASS
SortedSet<String> headSetDerived = new TreeSet<String>(headSet); // Make a TreeSet from a TreeSet.
sortedSet.removeAll(headSetDerived); // Succeeds. Why?
System.out.println("After: " + sortedSet);
我没有意识到headSet是由原始Set支持的。我现在在文档中看到。这解释了这种行为,其中第一次删除成功,而进一步删除引发异常。谢谢。 –