为什么会抛出并发修改异常

时间:2015-02-09 17:33:17

标签: java

当特定地图中有多个修改时,以下代码可以正常工作。但是当只有一个修改时,它会抛出并发修改异常

for(Map.Entry<String, List<String>> mapEntry : beanMap.entrySet()) {
    for(String dateSet : dateList) {
        String mName = mapEntry.getKey();
        boolean dateFound = false;
        if(beanMap.containsKey(dateSet)) {
            dateFound = true;
            System.out.println("    Found : "+mapEntry.getKey());
        }
        if(!dateFound)
        {
            Map<String, List<String>> modifiedMap = beanMap;
            List<String> newBeanList = new ArrayList<String>();
            dBean beanData = new Bean(dateSet+"NA","NA","NA",0,0,0);
            newBeanList.add(beanData);
            System.out.println("    Adding : "+dateSet+" "+"NA");
            modifiedMap.put(mName, newBeanList);
        }
    }
}

在上面的代码中,当修改&#34; modifiedMap&#34;时会抛出ConcurrentModificationException。只有一次。可能还有更多,但无法找到原因。

3 个答案:

答案 0 :(得分:6)

当您使用增强的for循环时,隐含的Iterator在幕后工作。您尝试使用以下行复制beanMap

Map<String, List<String>> modifiedMap = beanMap;

但是,这只会创建另一个引用同一个地图对象的引用变量。仍然只有一个地图,您正在修改它:

modifiedMap.put(mName, newBeanList);

Iterator然后检测到地图在尝试迭代到下一个条目时被修改,从而产生ConcurrentModificationException

在您迭代原始地图时,您可以使用Map创建另一个new,并put对该地图进行所有修改。

完成对原始地图的迭代后,您可以在其上调用the putAll method,传递新地图,以应用您想要的所有修改。

答案 1 :(得分:0)

使用此语法迭代时,不允许更改基础集合。集合以快速失败的方式实现,因此即使是单个更改也会引发异常。

如果您在访问元素时需要更改集合,请使用Iterator

答案 2 :(得分:0)

modifiedMap是对您正在迭代的相同地图beanMap的引用。您正在迭代时修改集合modifiedMap,因此异常。

相关问题