2010-08-18 86 views
5

Possible Duplicates:
Java: Efficient Equivalent to Removing while Iterating a Collection
Removing items from a collection in java while iterating over it如何在Java中修改對象時迭代對象?

我通過HashMap試圖循環:

Map<String, Integer> group0 = new HashMap<String, Integer>(); 

...在group0提取的每一個元素。這是我的方法:

// iterate through all Members in group 0 that have not been assigned yet 
for (Map.Entry<String, Integer> entry : group0.entrySet()) { 

    // determine where to assign 'entry' 
    iEntryGroup = hasBeenAccusedByGroup(entry.getKey()); 
    if (iEntryGroup == 1) { 
     assign(entry.getKey(), entry.getValue(), 2); 
    } else { 
     assign(entry.getKey(), entry.getValue(), 1); 
    } 
} 

這裏的問題是,每次調用assign()將從group0刪除元素,從而改變它的大小,從而導致出現以下錯誤:

Exception in thread "main" java.util.ConcurrentModificationException 
    at java.util.HashMap$HashIterator.nextEntry(HashMap.java:793) 
    at java.util.HashMap$EntryIterator.next(HashMap.java:834) 
    at java.util.HashMap$EntryIterator.next(HashMap.java:832) 
    at liarliar$Bipartite.bipartition(liarliar.java:463) 
    at liarliar$Bipartite.readFile(liarliar.java:216) 
    at liarliar.main(liarliar.java:483) 

那麼......我可以在group0中循環播放元素嗎?

+2

製作group0地圖的副本,並在循環播放group0時從副本中刪除元素? – sarahTheButterFly 2010-08-18 23:57:46

+0

@sarah ...好點。我會嘗試的。 – Hristo 2010-08-19 00:01:35

+0

@sarah ...通過group0複製到一個克隆HashMap給我的問題是,當我從group0中刪除時,我也從克隆中刪除。我如何克服這一點?我如何製作group0的獨立副本? – Hristo 2010-08-19 00:10:35

回答

7

其他人已經提到了正確的解決方案,但實際上並未將其拼寫出來。所以在這裏,它是:

Iterator<Map.Entry<String, Integer>> iterator = 
    group0.entrySet().iterator(); 
while (iterator.hasNext()) { 
    Map.Entry<String, Integer> entry = iterator.next(); 

    // determine where to assign 'entry' 
    iEntryGroup = hasBeenAccusedByGroup(entry.getKey()); 

    if (iEntryGroup == 1) { 
     assign(entry.getKey(), entry.getValue(), 2); 
    } else { 
     assign(entry.getKey(), entry.getValue(), 1); 
    } 

    // I don't know under which conditions you want to remove the entry 
    // but here's how you do it 
    iterator.remove(); 
} 

另外,如果你想安全地更改地圖在你的分配功能,你需要在迭代器(其中,你只能使用刪除功能,而且只有一次),以通過或輸入以更改值。

+0

謝謝......這正是我要找的! – Hristo 2010-08-19 14:31:24

0

如果您想在循環播放時修改集合,則需要使用實際的迭代器及其刪除方法。用foreach構造沒有任何辦法。

如果您嘗試在一次迭代中刪除多個條目,則需要循環未映射的某些內容。

Set<String> keys = new HashSet<String>(group0.keySet()); 
for (String key : keys) { 
    if (group0.containsKey(key)) { 
    Integer value = group0.get(key); 
    //your stuff 
    } 
} 
+0

'assign()'也可以從組0中刪除多於1個元素...所以有一次迭代會刪除group0中的所有元素而不需要第二次迭代的機會。你能發表代碼如何工作的迭代器? – Hristo 2010-08-19 00:04:40

0

在這種情況下,怎麼能assign修改group0?需要更多細節。通常,您不能在迭代集合的同時修改集合。您可以通過Iterator界面進行修改。

1

你的具體情況,我不會改變的HashMap的結構,但僅僅是空要刪除的價值。那麼如果你最終訪問一個空值就跳過它。

在一般情況下,我更喜歡,因爲他們特別容易想象使用棧這樣的事情,所以我往往有邊界條件較少的問題(只是保持啪「直到空)。

+0

啊......好主意:)但是使用堆棧在這裏是完全不正確的......例如,如果我想檢查一個元素是否存在,那麼在這裏的效率會非常低。對於我的目標,效率和速度是必須的。但我喜歡零空白的想法。 +1 – Hristo 2010-08-19 02:57:27