2013-01-14 29 views
0

我有一個將字節映射到字節集的映射。我想穿過地圖並對設置進行更改。如何迭代(並進行更改)作爲另一個集合的值的集合

private HashMap<Byte, HashSet<Byte>> table; 
... 
Iterator<Entry<Byte, HashSet<Byte>>> it = table.entrySet().iterator(); 
while(it.hasNext()) { 
    Map.Entry<Byte, HashSet<Byte>> pairs = it.next(); 
    byte node = pairs.getKey(); 
    HashSet<Byte> hSet = pairs.getValue(); 
    Iterator<Byte> setIter = hSet.iterator(); 
    while(setIter.hasNext()) { 
     byte sNode = setIter.next(); // Throws a ConcurrentModificationException 
     ... 
    } 
} 

當我嘗試迭代子迭代器時,此代碼拋出ConcurrentModificationException。我應該怎樣做才能在我的地圖中迭代並更改此集合?

+1

什麼類型你想改變什麼? –

+1

使用[Guava'HashMultimap'](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/HashMultimap.html)可能會更好。 –

+0

嘗試模擬你的問題。但代碼對我來說工作得很好。你可以發佈任何額外的細節? – Renjith

回答

1

我覺得你得到的異常因爲你在迭代期間修改了這個集合(在問題中沒有包含的行中)。如果它們檢測到集合的結構已被更改,那麼「fail-fast」迭代器會拋出它。

請注意,此異常並不總是表示某個對象已被另一個線程同時修改。如果單個線程發出違反對象合約的一系列方法調用,則該對象可能會拋出此異常。例如,如果一個線程在使用快速迭代器迭代集合的同時直接修改集合,迭代器將拋出此異常。

http://docs.oracle.com/javase/7/docs/api/java/util/ConcurrentModificationException.html

如果從集合,而你迭代只刪除,你可以使用迭代器,而不是設置方法remove方法。如果您還想在迭代過程中添加到集合中,則需要創建集合的副本,並對其進行迭代(但這種情況不太可能,您可以添加到集合而不會迭代它...)

+0

+1表示問題不是由引發異常的行引起的。 –

1

嘗試類似的東西:

for(Byte node : table.keySet()) { 
    HashSet<Byte> hSet = table.get(node); 
    Iterator<Byte> setIter = hSet.iterator(); 
    while(setIter.hasNext()) { 
     byte sNode = setIter.next(); 
     ... 
    } 
} 

如果你想在Set副本修改hSet你最好的辦法可能是循環:

for(Byte node : table.keySet()) { 
    HashSet<Byte> hSet = table.get(node); 

    for (Byte sNode : new HashSet<Byte>(hSet)) { 
     //do things which modifies the original hSet 
    } 
}