com.google.common.collect.Sets.SetView ошибка или функция? - PullRequest
5 голосов
/ 13 декабря 2011

Здравствуйте, у меня есть этот кусок кода:

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)

это нормально?или небольшая ошибка ...

1 Ответ

9 голосов
/ 13 декабря 2011

SetView представляет собой представление пересечения этих наборов, а не копию. Из документов Гуава:

Неизменяемое представление набора, которое может поддерживаться другими наборами; этот вид изменится, как и наборы поддержки.

Итак, когда вы вызываете set1.removeAll(x) и передаете представление, вы, по сути, пытаетесь удалить из set1, перебирая часть себя. Это причина для ConcurrentModificationException.

Чтобы достичь того, что вы пытаетесь сделать, взгляните на SetView.immutableCopy().

Например:

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