ConcurrentModificationException-检查共修改(ArrayList.java)

ConcurrentModificationException-检查共修改(ArrayList.java),java,arraylist,hashmap,Java,Arraylist,Hashmap,对于下面的带有哈希映射的java程序,ConcurrentModification异常抛出,我已经标记了程序中抛出异常的行 我现在已经跳过了将数据插入HashMap的登录 import java.util.ArrayList; import java.util.HashMap; public class MainClass { public static void main(String[] args) { ArrayList<HashMap<S

对于下面的带有哈希映射的java程序,ConcurrentModification异常抛出,我已经标记了程序中抛出异常的行

我现在已经跳过了将数据插入HashMap的登录

import java.util.ArrayList;
 import java.util.HashMap;

 public class MainClass {

     public static void main(String[] args) {

         ArrayList<HashMap<String, ArrayList<String>>> arrMain = new ArrayList<HashMap<String, ArrayList<String>>>();

         HashMap<String, ArrayList<String>> hm = new HashMap<String, ArrayList<String>>();

         ArrayList<String> strings = new ArrayList<String>();

         // Code to build the above Maps with all required Data, Skipped for Now

         //******************Scenario 1****************
         for (HashMap<String, ArrayList<String>> dataMap : arrMain) { //ConcurrentModification Exception
             for (String s : dataMap.get("Key")) {
                 ArrayList<String> newStrings = new ArrayList<String>();
                 newStrings.addAll(dataMap.get("Key")); 
                 newStrings.add("New String");
                 dataMap.put("Key", newStrings);
             }

         }

         //******************Scenario 2****************
         for (HashMap<String, ArrayList<String>> dataMap : arrMain) {//ConcurrentModification Exception
             for (String s : dataMap.get("Key")) {
                 dataMap.get("Key").add("New String"); 
             }

         }

     }

 }

当您尝试在迭代时修改集合时,将得到
ConcurrentModificationException
。您可以尝试使用
迭代器来避免这种情况

例如:
Iterator
with
Map

    Map<String, String> map = new HashMap<>();
    map.put("a", "a1");
    map.put("b", "b1");
    map.put("c", "c1");
    System.out.println(map);
    Iterator it = map.entrySet().iterator();
    while (it.hasNext()) {
        Map.Entry pairs = (Map.Entry) it.next();
        System.out.println(pairs.getKey() + " = " + pairs.getValue());
        it.remove(); // no a ConcurrentModificationException
    }
    System.out.println(map);

当您尝试在迭代时修改集合时,将得到
ConcurrentModificationException
。您可以尝试使用
迭代器来避免这种情况

例如:
Iterator
with
Map

    Map<String, String> map = new HashMap<>();
    map.put("a", "a1");
    map.put("b", "b1");
    map.put("c", "c1");
    System.out.println(map);
    Iterator it = map.entrySet().iterator();
    while (it.hasNext()) {
        Map.Entry pairs = (Map.Entry) it.next();
        System.out.println(pairs.getKey() + " = " + pairs.getValue());
        it.remove(); // no a ConcurrentModificationException
    }
    System.out.println(map);
你可以用

一个哈希表,支持检索的完全并发性和更新的可调整预期并发性

这个类遵循与Hashtable相同的功能规范,并且包括与Hashtable的每个方法对应的方法版本

但是,即使所有操作都是线程安全的,检索操作也不需要锁定,并且不支持以阻止所有访问的方式锁定整个表

该类在依赖于其线程安全性而不依赖于其同步细节的程序中与哈希表完全互操作


您可以使用迭代器迭代器设计为一次只能由一个线程使用。它们不会抛出ConcurrentModificationException。

当对象的并发修改不允许时,检测到该修改的方法可能会引发此异常

例如,通常不允许一个线程在另一个线程迭代集合时修改集合

另见
您可以使用

一个哈希表,支持检索的完全并发性和更新的可调整预期并发性

这个类遵循与Hashtable相同的功能规范,并且包括与Hashtable的每个方法对应的方法版本

但是,即使所有操作都是线程安全的,检索操作也不需要锁定,并且不支持以阻止所有访问的方式锁定整个表

该类在依赖于其线程安全性而不依赖于其同步细节的程序中与哈希表完全互操作


您可以使用迭代器迭代器设计为一次只能由一个线程使用。它们不会抛出ConcurrentModificationException。

当对象的并发修改不允许时,检测到该修改的方法可能会引发此异常

例如,通常不允许一个线程在另一个线程迭代集合时修改集合

另见

您在代码中标记了2个
ConcurrentModificationException
点,但只有一个点是可复制和合理的

第二个:

for (HashMap<String, ArrayList<String>> dataMap : arrMain) {
     for (String s : dataMap.get("Key")) { // HERE 
         dataMap.get("Key").add("New String"); 
     }
}
在添加一个元素(修改它)之后,
循环将继续。在迭代过程中,将元素添加到列表中。这会导致
ConcurrentModificationException
(在引擎盖下,增强的
for
使用列表的迭代器遍历其元素,并且迭代器
next()
方法在创建迭代器后修改列表时抛出此异常)


代码中的第一个点指示了
ConcurrentModificationException
,它不会导致异常,因为您迭代了一个列表,并修改了另一个列表,即在
for
循环中创建的新列表。但我怀疑这是您真正想要做的。

您在代码中标记了2个
ConcurrentModificationException
点,但只有一个点是可复制和合理的

第二个:

for (HashMap<String, ArrayList<String>> dataMap : arrMain) {
     for (String s : dataMap.get("Key")) { // HERE 
         dataMap.get("Key").add("New String"); 
     }
}
在添加一个元素(修改它)之后,
循环将继续。在迭代过程中,将元素添加到列表中。这会导致
ConcurrentModificationException
(在引擎盖下,增强的
for
使用列表的迭代器遍历其元素,并且迭代器
next()
方法在创建迭代器后修改列表时抛出此异常)


代码中的第一个点指示了
ConcurrentModificationException
,它不会导致异常,因为您迭代了一个列表,并修改了另一个列表,即在
for
循环中创建的新列表。但我怀疑这是您真正想要做的。

您不能在hashmap上迭代并同时使用addall或add。这就像同时读取和更改一个位置。不能在hashmap上迭代,同时使用addall或add。这就像同时读取和更改位置一样。
for (HashMap<String, ArrayList<String>> dataMap : arrMain) {
     for (String s : dataMap.get("Key")) { // HERE 
         dataMap.get("Key").add("New String"); 
     }
}
dataMap.get("Key").add("New String");