为什么迭代器不抛出并发修改异常?
why iterator is not throwing concurrentmodification exception?
为什么这个方法不抛出并发修改?
如果 if(next.equals("3") 它没有。但是,我将它更改为 equals("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
这取决于 HashMap
的实施。
如果你 运行 在 Java 7 下,那么对于 if (next.equals("3"))
它将抛出一个 ConcurrentModificationException
,而对于 1
,它不会' t.
如果你 运行 在 Java 8 下,那么 3
不会抛出异常,而 1
会抛出异常。
原因是当您在 Java 7 下迭代映射时,第一个键将是 3
,最后一个是 1
。所以你在修改值的同时还有其他值要迭代。
在Java 8下,迭代中的第一个键是1
,最后一个是3
。
如果您在遇到最后一个键时修改地图,它不会检查该修改,因为它只会在您下次尝试调用 next()
时检查它,但在最后一个值之后,hasNext()
returns false,所以不调用next()
,避免了异常。
在循环内更改地图后尝试访问 iterator.next().getKey();
之前,不会抛出 ConcurrentModificationException
。在示例中 "3"
是原始映射中的最后一个键,并且在抛出异常之前退出循环。对于原始映射中除最后一个键之外的每个键,都会抛出异常。
ConcurrentModificationException
当迭代器到达下一个地图键时抛出,如果您在上一步中向地图添加了新键。因此,如果您测试的键不是地图中的最后一个键,您只会得到异常。在你的情况下 3
肯定是最后一个。
注意:由于 HashMap
没有顺序,在一台机器上 3
可能是最后一个,在其他机器上 1
或 2
可能是最后一个。
为什么这个方法不抛出并发修改? 如果 if(next.equals("3") 它没有。但是,我将它更改为 equals("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
这取决于 HashMap
的实施。
如果你 运行 在 Java 7 下,那么对于 if (next.equals("3"))
它将抛出一个 ConcurrentModificationException
,而对于 1
,它不会' t.
如果你 运行 在 Java 8 下,那么 3
不会抛出异常,而 1
会抛出异常。
原因是当您在 Java 7 下迭代映射时,第一个键将是 3
,最后一个是 1
。所以你在修改值的同时还有其他值要迭代。
在Java 8下,迭代中的第一个键是1
,最后一个是3
。
如果您在遇到最后一个键时修改地图,它不会检查该修改,因为它只会在您下次尝试调用 next()
时检查它,但在最后一个值之后,hasNext()
returns false,所以不调用next()
,避免了异常。
在循环内更改地图后尝试访问 iterator.next().getKey();
之前,不会抛出 ConcurrentModificationException
。在示例中 "3"
是原始映射中的最后一个键,并且在抛出异常之前退出循环。对于原始映射中除最后一个键之外的每个键,都会抛出异常。
ConcurrentModificationException
当迭代器到达下一个地图键时抛出,如果您在上一步中向地图添加了新键。因此,如果您测试的键不是地图中的最后一个键,您只会得到异常。在你的情况下 3
肯定是最后一个。
注意:由于 HashMap
没有顺序,在一台机器上 3
可能是最后一个,在其他机器上 1
或 2
可能是最后一个。