我希望以下代码中有ConcurrentModificationException
,但它运行正常。
HashMap<Integer, String>table1 = new HashMap<Integer, String>();
table1.put(1, "Sam");
table1.put(2, "Jon");
table1.put(3, "Doe");
Iterator itr1 = table1.entrySet().iterator();
table1.put(3, "DONN");
while(itr1.hasNext())
{
System.out.println("---Value--" + itr1.next());
}
根据HashMap
的JavaDoc:
所有这个类的“集合视图方法”返回的迭代器是快速失败的:如果在创建迭代器之后的任何时候对映射进行结构修改,除了通过迭代器自己的remove方法之外,迭代器将会抛出ConcurrentModificationException。
因为我在获得HashMap
之后修改Iterator
因为我应该获得ConcurrentModificationException
。为什么不扔?
答案 0 :(得分:4)
在HashMap
的当前实现中,为现有键添加条目不被视为结构修改,并且永远不会触发ConcurrentModificationException
。尝试使用新密钥,例如table1.put(4, "UPS");
获得ConcurrentModificationException
。
答案 1 :(得分:2)
您正在修改HashMap
而不是您在其上获得的entrySet,并且您正在iterator
上获取entrySet
:
根据entrySet
方法javaDoc:
如果在对集合进行迭代时修改了映射(除非通过迭代器自己的remove操作,或者通过迭代器返回的映射条目上的setValue操作),迭代的结果是未定义的。
所以你没有得到ConcurrentModificationException
。
以下是entrySet的完整说明:
返回此映射中包含的映射的Set视图。该集由地图支持,因此对地图的更改将反映在集中,反之亦然。如果在对集合进行迭代时修改了映射(除非通过迭代器自己的remove操作,或者通过迭代器返回的映射条目上的setValue操作),迭代的结果是未定义的。该集支持元素删除,它通过Iterator.remove,Set.remove,removeAll,retainAll和clear操作从地图中删除相应的映射。它不支持add或addAll操作。
答案 2 :(得分:2)
尝试table1.put(4, "DONN")
并且迭代器将因ConcurrentModificationException而失败。 table1.put(3, "DONN")
不会更改地图结构,只会替换key = 3的值,因为它已经存在