简体   繁体   English

hashmap获取并发修改异常的问题

[英]issue with hashmap getting concurrent modification exception

I am getting the below error while using map and performing some remove.How to avoid this ? 使用地图并执行一些删除操作时出现以下错误。如何避免这种情况?

Caused by: java.util.ConcurrentModificationException
    at java.util.HashMap$HashIterator.nextEntry(HashMap.java:793)
    at java.util.HashMap$EntryIterator.next(HashMap.java:834)
    at java.util.HashMap$EntryIterator.next(HashMap.java:832)


   Map<FormField, Object> ItemMap = domainItem.getValues();         
   for (Map.Entry<FormField, Object> ValMap : ItemMap.entrySet()) {         
       List<Field> groupIdList = Mapper.getGroupId(groupFieldId);           
       for (Field field : groupIdList) {
           ItemMap.put(new FormField(field), domainItem.getDomainItemLinkId());
       }
       ItemMap.remove(ValMap.getKey());
   }

Update: 更新:

Use Iterator and ConcurrentHashMap to avoid this scenario 使用Iterator和ConcurrentHashMap避免这种情况

Following won't throw exception 跟随不会抛出异常

    Map<Integer, String> map = new ConcurrentHashMap<Integer, String>();
    map.put(1, "a");
    map.put(2, "b");
    map.put(3, "c");
    map.put(4, "d");
    for (Iterator<Integer> keys = map.keySet().iterator(); keys.hasNext();) {
        Integer key = keys.next();
        String val = map.get(key);
        map.remove(key);
    }

or use another map while iterating and at the end copy it to source 或在迭代时使用其他地图,最后将其复制到源

for example: 例如:

    Map<Integer, String> dummy = new HashMap<Integer, String>();
    map.put(1, "a");
    map.put(2, "b");
    map.put(3, "c");
    map.put(4, "d");
    dummy.putAll(map);
    for (Iterator<Integer> keys = dummy.keySet().iterator(); keys.hasNext();) {
        Integer key = keys.next();
        String val = map.get(key);
        map.remove(key);
    }
    System.out.println(map);

A Map is sorted by the keys in the key-value pairs. 映射按键值对中的键排序。 When you add or remove elements from the Map while you are iterating through them, the program essentially loses track of "where" in the Map it is. 当您遍历地图时在地图中添加或删除元素时,该程序实际上会失去对地图中“位置”的跟踪。

To get around this, try making a separate, temporary transfer Map. 要解决此问题,请尝试制作一个单独的临时传输地图。 There is also a class called Iterator which might suit your needs. 还有一个称为Iterator的类,它可能适合您的需求。

One way to avoid this issue is to iterate over a copy. 避免此问题的一种方法是遍历副本。

for (Map.Entry<FormField, Object> ValMap : 
     new HashMap<FormField, Object>(ItemMap).entrySet()) {

can be done without a copy of the map, execute this example and take a look at the code: 无需复制地图即可完成操作,执行此示例,然后看一下代码:

public static void main(String[] args)
  {

    System.out.println("creating map ...");

    Map<String, String> dummyMap = new HashMap<>();
    while (dummyMap.size() < 10)
    { dummyMap.put(String.valueOf(new Random().nextInt()), String.valueOf(new Random().nextInt())); }


    System.out.println("start, map size: " + dummyMap.size() + ", keys=" + dummyMap.keySet());


    System.out.print("going to remove: ");
    for (Iterator<String> keys = dummyMap.keySet().iterator(); keys.hasNext(); )
    {
      final String key = keys.next();

      // delete map entries per random
      if(new Random().nextInt(3)>1)
      {
        System.out.print(key+" ");
        keys.remove();
      }
    }
    System.out.print("\n");

    System.out.println("done, map size: " + dummyMap.size() + ", keys=" + dummyMap.keySet());
  }

and take a look at this similar question . 看看这个类似的问题

HTH, HTH,

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

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