2011-11-28 96 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