在HashMap中澄清@ConcurrentModificationException

时间:2014-03-06 11:50:35

标签: java iterator hashmap

我希望以下代码中有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。为什么不扔?

3 个答案:

答案 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的值,因为它已经存在