迭代hashmap时,我没有得到ConcurrentModification Exception

时间:2014-07-28 10:34:50

标签: java

值对Hashmap.while迭代该映射我在我没有得到Exception时插入另外1个键值对。当并发修改异常时,任何人都可以帮助我。

mycode的:

public static void main(String[] args) {
        Map<String, String> hMap = new HashMap<String, String>();
        hMap.put("FIRST", "1");
        hMap.put("SECOND", "2");
        hMap.put("THIRD", "3");
        hMap.put("FOURTH", "4");
        hMap.put("FIFTH", "5");
        hMap.put("SIXTH", "6");
        System.out.println("HashMap before iteration : " + hMap);
        Iterator<String> hashMapIterator = hMap.keySet().iterator();
        while (hashMapIterator.hasNext()) {
            String key = hashMapIterator.next();
            if (key.equals("FOURTH")) {
                System.out.println("key = " + key);
                hMap.put("sfsfsfsf2", "dsgfdsg");
            }
        }
        System.out.println("HashMap after iteration : " + hMap);
    }

2 个答案:

答案 0 :(得分:0)

ConcurrentModificationException的出现是因为IteratorMap#put都可以同时修改Map。为规避这一点,请为#put操作创建临时存储空间:

Map<String, String> tmp = new HashMap<String, String>();
//...
Iterator<String> iter = hMap.keySet().iterator();
while(iter.hasNext()) {
    //...
    tmp.put("asdfasdf", "aasdfasdfas");
}
for (Entry<String, String> ops : tmp.entrySet())
    hMap.put(ops.getKey(), ops.getValue());

一个简单的观察:如果#put在迭代时添加一个新键,迭代器应该如何知道它必须在其新的迭代序列中“跳回”以获得新添加的键?

其他地图

我的猜测ConcurrentModificationException可能不会发生key来自#put的{​​{1}}以使其位置(在entrySet之后当前迭代的元素,以便“旧”Iterator仍然与“新”Iterator一致,因为它已经交付“新”entrySet具有相同顺序的元素。但这只是我猜测为什么它可能不会发生。这样的编码非常糟糕,因为现有代码将取决于Iterator - hashCode的{​​{1}}的实现细节。

的HashMap

key的{​​{3}}跟踪HashMap结构修改

  

此HashMap经过结构修改的次数结构修改是指更改HashMap中映射数量或以其他方式修改其内部结构(例如,重新散列)的修改。此字段用于在HashMap的Collection-views上快速生成迭代器。 (请参阅ConcurrentModificationException)。

当请求Map前进时,检查HashIterator自创建以来是否已更改。如果有,则抛出modCount。这意味着如果您只更改与键关联的值,但不以任何方式更改键,则不会抛出它。

答案 1 :(得分:0)

可能获得ConcurentModificationException,但没有保证。密钥集的Map(和HashMapcontract为:

  

如果在对集合进行迭代时修改了地图   (除非通过迭代器自己的删除操作),的结果   迭代未定义

某些实施尝试快速失败,但同样没有保证。 Hashmap javadoc甚至说:

  

请注意,无法保证迭代器的快速失败行为   一般来说,不可能做出任何硬性保证   存在不同步的并发修改。快速失败   迭代器抛出ConcurrentModificationException就是尽力而为   基础。因此,编写一个依赖的程序是错误的   关于这个例外的正确性