2011-11-28 89 views
0

假設您有一個HashMap m 並且裏面已經有一個關鍵值對<"key1", object>java hashMap併發修改異常

你能做到以下幾點嗎?

m.put("newkey", m.remove("key1")) 

你會得到ConcurrentModificationException

+4

問;-) – Matteo

+0

這是爲什麼被關閉之前只是試一下呢?我認爲這個問題很清楚......? –

+0

@Matteo在軟件編程的世界裏,有一兩次嘗試不揭示真正的答案,你看到的是我們代碼的一個片段。事端問題可能難以重現,特別是線程問題。即使在嘗試之後,我仍然想知道它爲什麼起作用,或者爲什麼它不起作用,我個人認爲給人選擇關閉帖子是非常糟糕的做法。因爲這裏有太多人,聰明的話那麼平均 –

回答

7

只要它不在迭代hashMap條目的循環體中,就可以這樣做。可行的方法是在put操作之前,remove操作將執行並完成,因此它在語義上等同於2行。

+0

謝謝,爲什麼它不能在循環?謝謝 –

+1

因爲如果循環遍歷映射,您不能修改底層映射而不會觸發concurrentModificationException,因爲您可能正在插入一個新的行,該行在迭代器中的當前位置之前顯示在映射中(例如)。 – Chris

+0

@shanyangqu你可以在循環中做到這一點,除非你使用迭代器在該hashmap上(使用foreach循環等)。那些迭代器檢查是否有通過它們進行的修改並拋出'ConcurrentModificationException'。 – Thomas

0

由於m.remove返回先前與該關鍵字關聯的對象,因此無論您喜歡如何,都應該可以使用該對象。所以不,我不相信你會得到一個例外。

1

剛剛爲您測試過。

Map<String, Object> map = new HashMap<String, Object>();   
map.put("k1", Integer.valueOf(999));   
map.put("k2", map.remove("k1")); 
System.out.println(map.get("k2")); 

打印:

 
999 

無異常(ConcurrentModificationException)。

0

它們實際上不是同時發射。首先調用remove,完成後調用get,所以我沒有理由爲什麼會有異常。

見這個,如果你需要修改循環時: Iterate through a HashMap