为什么这个方法不会抛出并发修改? if if(next.equals(" 3")它没有。但是,我将它改为等于(" 1")它确实。这里发生了什么?
private void checkConcurrentModification(){
Map<String, Integer> map = new HashMap<>();
map.put("1", 1);
map.put("2", 2);
map.put("3", 3);
Iterator<Entry<String, Integer>> iterator = map.entrySet().iterator();
while(iterator.hasNext()){
String next = iterator.next().getKey();
map.put(next, 1);
if(next.equals("3")){ //does not throw exception
//if(next.equals("1")){ //throws exception
map.put("4", 4);
}
}
for(Entry<String, Integer> entry : map.entrySet()){
System.out.println("entry key and value" +entry.getKey() + " : " +entry.getValue());
}
}
prints:
entry key and value1 : 1
entry key and value2 : 1
entry key and value3 : 1
entry key and value4 : 4
答案 0 :(得分:2)
这取决于HashMap
。
如果你在Java 7下运行它,那么使用if (next.equals("3"))
它会抛出ConcurrentModificationException
,而1
则会抛出3
。
如果你在Java 8下运行它,那么使用1
它将不会抛出异常,而3
则会抛出异常。
原因是当您在Java 7下迭代地图时,第一个键将是1
,最后一个键是1
。所以你在修改值的同时还有其他值要迭代。
在Java 8下,迭代中的第一个键是3
,最后一个键是next()
。
如果您在遇到最后一个密钥时修改了地图,它将不会检查该修改,因为它只会在您下次尝试呼叫hasNext()
时检查它,但在最后一个值之后{{1返回false,因此不会调用next()
并避免异常。
答案 1 :(得分:2)
在您在循环中更改地图后尝试访问ConcurrentModificationException
之前,不会抛出iterator.next().getKey();
。在示例中,"3"
是原始映射中的最后一个键,并且在抛出异常之前退出循环。对于原始地图中除最后一个之外的每个键,都会抛出异常。
答案 2 :(得分:1)
ConcurrentModificationException
。因此,如果您测试的密钥不是地图中的最后一个密钥,则只会获得异常。在你的情况下,3
肯定是最后一个。
注意:由于HashMap
没有订单,因此在一台计算机上3
可能是最后一次,在其他1
或2
上可能是。