2011-12-13 101 views
4

你好我有這段代碼:com.google.common.collect.Sets.SetView錯誤或功能?

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 ...

回答

8

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); 
+0

聲音效果良好;但如果我做immutableCopy(),它會從視圖中刪除我的對象不是?這種方式我不能從我的2套移除所有...是否更好地做新的HashSet(SetView)? – user952887

+0

@ user952887 - 無論哪種方式都可以。看我的編輯。 –

+0

它的工作非常感謝,我這樣做:set1.removeAll(x.immutableCopy()); set2.removeAll(x.immutableCopy());謝謝你的時間。 – user952887