com.google.common.collect.Sets.SetView bug or feature?

馋奶兔 提交于 2019-12-23 10:39:50

问题


Hello I've this piece of code:

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);
}

and it throws

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)

is this a normal? or a small bug...


回答1:


SetView is a view of the intersection of these sets, not a copy. From the Guava docs:

An unmodifiable view of a set which may be backed by other sets; this view will change as the backing sets do.

So, when you call set1.removeAll(x) and pass in the view, you're essentially trying to remove from set1 while looping over part of itself. This is the reason for the ConcurrentModificationException.

To achieve what you're trying to do, have a look at SetView.immutableCopy().

For example:

SetView<Integer> intersectionView = Sets.intersection(set1, set2);
ImmutableSet<Integer> intersectionCopy = intersectionView.immutableCopy();
set1.removeAll(intersectionCopy);
set2.removeAll(intersectionCopy);


来源:https://stackoverflow.com/questions/8490901/com-google-common-collect-sets-setview-bug-or-feature

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!