2013-11-01 36 views
8

我有下面這段代碼,而且我通過執行以下行得到一個ConcurrentModificationException的:ConcurrentModificationException的在修改的Collection

filterCardsToDevice(getCollection()); 

代碼:

private List<MyClass> filterCardsToDevice(Collection<MyClass> col) { 
    final List<MyClass> newList = new ArrayList<MyClass>(); 

    for (MyClass myObj : col) { 
     long id = myObj.getId(); 
     if (id < 0 || id > 0xFFFFFFFFl) { 
      // just a log here 
     } else { 
      newList.add(myObj); 
     } 
    } 

    return newList; 
} 

private final Map<Long, MyClass> map = new HashMap<Long, MyClass>(); 

public Collection<MyClass> getCollection() { 
    synchronized (map) { 
     return Collections.unmodifiableCollection(map.values()); 
    } 
} 

堆棧是:

at java.util.HashMap$HashIterator.nextEntry(HashMap.java:841)     
at java.util.HashMap$ValueIterator.next(HashMap.java:871)     
at java.util.Collections$UnmodifiableCollection$1.next(Collections.java:1010) 

恰恰在每行上:

for (MyClass myObj : col) { 

我不明白爲什麼會發生此錯誤,因爲我沒有修改列表。

回答

13

請注意,該Collections.unmodifiable*不復制收集數據,但只包裝原始集合在一個特殊的包裝。所以如果你修改了原始的集合,你可以得到這個錯誤。


如果你想創建真正獨立不可改變的集合實例:

Collections.unmodifiableCollection(new ArrayList<>(map.values())); 
5

你必須在另一個線程來更新map,而你是通過迭代colmap#valuesCollections.unmodifiableCollection都會返回現有數據結構的視圖,因此您正在迭代的內容(這是您的堆棧跟蹤所見證的)是您的map的條目集。

相關問題