您好,我有这段代码:
public static void main(String[] args) {
Set<Integer> set1 = new HashSet<Integer>();
Set<Integer> set2 = new HashSet<Integer>();
set1.add(1);
set1.add(2);
set1.add(3);
set1.add(4);
set1.add(5);
set2.add(4);
set2.add(5);
set2.add(6);
set2.add(7);
set2.add(8);
SetView<Integer> x = Sets.intersection(set1, set2);
set1.removeAll(x);
set2.removeAll(x);
}
它抛出
Exception in thread "main" java.util.ConcurrentModificationException
at java.util.HashMap$HashIterator.nextEntry(HashMap.java:841)
at java.util.HashMap$KeyIterator.next(HashMap.java:877)
at com.google.common.collect.Iterators$7.computeNext(Iterators.java:627)
at com.google.common.collect.AbstractIterator.tryToComputeNext(AbstractIterator.java:141)
at com.google.common.collect.AbstractIterator.hasNext(AbstractIterator.java:136)
at java.util.AbstractSet.removeAll(AbstractSet.java:142)
at com.Main2.main(Main2.java:30)
这是正常的吗?或一个小 bug ...
最佳答案
SetView
是这些集合的交集的 View ,而不是副本。从 Guava 文档中:
因此,当您调用set1.removeAll(x)
并传递 View 时,您实际上是在尝试从set1
中删除,同时遍历其自身的一部分。这就是 ConcurrentModificationException
的原因。
要实现您要执行的操作,请查看 SetView.immutableCopy()
。
例如:
SetView<Integer> intersectionView = Sets.intersection(set1, set2);
ImmutableSet<Integer> intersectionCopy = intersectionView.immutableCopy();
set1.removeAll(intersectionCopy);
set2.removeAll(intersectionCopy);