当Hashmap大小没有改变时,为什么Hashmap会抛出ConcurrentModificationException

时间:2018-04-29 11:03:03

标签: java hashmap

我正在研究hashmap,我可以知道迭代地图时。 hashmap内部保留了hashmap大小的跟踪,如果大小hashmap中有任何更改,则抛出ConcurrentModificationException。

以同样的观点前进。 看看这段代码

    HashMap<String, String> myMap = new HashMap<>();
    myMap.put("1", "1");
    myMap.put("2", "2");
    myMap.put("3", "3");
    myMap.put("4", "4");

            System.out.println("HashMap before iterator size before : " +myMap.size());
    try {
        for(String key : myMap.keySet()){
                myMap.remove("3");
                myMap.remove("4");
                myMap.put("5", "new8"); 
                myMap.put("6", "new9");
        }
    } catch(ConcurrentModificationException exception) {
        System.out.println("HashMap before iterator size after : " +myMap.size());
    }
    System.out.println("HashMap before iterator fourth : "+myMap);

同样的输出是:

HashMap before iterator size before 4
HashMap before iterator size after  4
HashMap before iterator fourth : {1=1, 2=2, 5=new8, 6=new9}

为什么hashmap会在这种情况下抛出错误?

1 个答案:

答案 0 :(得分:2)

  

hashmap内部跟踪hashmap大小,如果大小hashmap有任何变化则抛出ConcurrentModificationException

这是不正确的。要决定是否抛出ConcurrentModificationExceptionHashMap会跟踪修改的数量,而不是Map的大小。添加两个条目并删除两个条目会使修改计数增加4.因此异常。

Javadoc声明:

  

所有这个类的“集合视图方法”返回的迭代器是快速失败的:如果在创建迭代器之后的任何时候对映射进行结构修改,除了通过迭代器自己的remove方法之外,迭代器将会抛出ConcurrentModificationException。

实际添加或删除条目的任何putremove操作都会导致Map的结构修改,因此myMap.keySet()上的迭代器将抛出ConcurrentModificationException }。