简体   繁体   English

在HashMap中澄清@ConcurrentModificationException

[英]Clarification @ConcurrentModificationException in HashMap

I am expecting a ConcurrentModificationException in the follow code, but it's working fine. 我期待以下代码中的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());
    }

As per the JavaDoc for HashMap : 根据JavaDoc for HashMap

The iterators returned by all of this class's "collection view methods" are fail-fast: if the map is structurally modified at any time after the iterator is created, in any way except through the iterator's own remove method, the iterator will throw a ConcurrentModificationException. 所有这个类的“集合视图方法”返回的迭代器都是快速失败的:如果在创建迭代器之后的任何时候对映射进行结构修改,除了通过迭代器自己的remove方法之外,迭代器将抛出ConcurrentModificationException。 。

So since I am modifying the HashMap after getting the Iterator I should be getting the ConcurrentModificationException . 因为我在获取Iterator之后修改了HashMap ,所以我应该得到ConcurrentModificationException Why is it not throwing? 为什么不扔?

Putting an entry for an existing key is not considered a structural modification in the current implementation of HashMap and will never trigger a ConcurrentModificationException . 现有密钥设置条目不会被视为当前HashMap实现中的结构修改 ,并且永远不会触发ConcurrentModificationException Try putting with a new key, eg table1.put(4, "UPS"); 尝试使用新密钥,例如table1.put(4, "UPS"); to get a ConcurrentModificationException . 获取ConcurrentModificationException

You are modifying the HashMap not the entrySet that you are obtaining on it, and here you are obtaining the iterator over the entrySet : 您正在修改HashMap而不是您在其上获取的entrySet,并且您在此处获取了entrySetiterator

As per entrySet method javaDoc: 根据entrySet方法javaDoc:

If the map is modified while an iteration over the set is in progress (except through the iterator's own remove operation, or through the setValue operation on a map entry returned by the iterator) the results of the iteration are undefined. 如果在对集合进行迭代时修改了映射(除非通过迭代器自己的remove操作,或者通过迭代器返回的映射条目上的setValue操作),迭代的结果是未定义的。

So you are not getting ConcurrentModificationException . 所以你没有得到ConcurrentModificationException

Here is the full explaination of entrySet: 以下是entrySet的完整说明:

Returns a Set view of the mappings contained in this map. 返回此映射中包含的映射的Set视图。 The set is backed by the map, so changes to the map are reflected in the set, and vice-versa. 该集由地图支持,因此对地图的更改将反映在集中,反之亦然。 If the map is modified while an iteration over the set is in progress (except through the iterator's own remove operation, or through the setValue operation on a map entry returned by the iterator) the results of the iteration are undefined. 如果在对集合进行迭代时修改了映射(除非通过迭代器自己的remove操作,或者通过迭代器返回的映射条目上的setValue操作),迭代的结果是未定义的。 The set supports element removal, which removes the corresponding mapping from the map, via the Iterator.remove, Set.remove, removeAll, retainAll and clear operations. 该集支持元素删除,它通过Iterator.remove,Set.remove,removeAll,retainAll和clear操作从地图中删除相应的映射。 It does not support the add or addAll operations. 它不支持add或addAll操作。

try table1.put(4, "DONN") and iterator will fail with ConcurrentModificationException. 尝试table1.put(4, "DONN")并且迭代器将因ConcurrentModificationException而失败。 table1.put(3, "DONN") does not change map structure but just replaces value for key=3 since it's already there table1.put(3, "DONN")不会更改地图结构,只是替换key = 3的值,因为它已经存在

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM