繁体   English   中英

如何在避免ConcurrentModificationException的同时迭代HashMap

[英]How to iterate over a HashMap while avoiding ConcurrentModificationException

我有一个HashMap,其类型为HashMap<String,HashMap<String,int>>现在我需要遍历此HashMap并删除任何键的值为0的内部HashMap。

如果这样的移除使内部HashMap为空,则内部HashMap的对应键将从外部HashMap中移除。 我尝试对其进行迭代,然后删除符合要求的元素,但这引发了ConcurrentModificationException

我尝试了以下代码:

synchronized(MyConstants.cliListUpdateList)
{
    synchronized(MyConstants.cliList)
    {
        outerEntries = MyConstants.cliListUpdateList.entrySet();
        outerIterator = outerEntries.iterator();

        while(outerIterator.hasNext())
        {
            outerEnt = (Entry) outerIterator.next();
            innerHashMap = (HashMap) outerEnt.getValue();
            synchronized(innerHashMap)
            {//synchronize innerhashmap
            innerEntries = innerHashMap.entrySet();
            innerIterator = innerEntries.iterator();
            synchronized(innerIterator)
            {
            while(innerIterator.hasNext())
            {
                innerEnt = (Entry) innerIterator.next();
                int k = Integer.parseInt((String)innerEnt.getValue());
                if(k==0)
                {
                    innerHashMap.remove(innerEnt.getKey());
                    if(innerHashMap.isEmpty())
                    {
                        MyConstants.cliListUpdateList.remove(outerEnt.getKey());
                    }

                    ArrayList ports = (ArrayList) MyConstants.cliList.get(outerEnt.getKey());
                    ports.remove((String)innerEnt.getKey());
                    if(ports.isEmpty())
                    {
                        MyConstants.cliList.remove(outerEnt.getKey());
                    }
                }
                else
                {
                    k--;
                    innerHashMap.put(innerEnt.getKey(), k+"");
                    MyConstants.cliListUpdateList.put(outerEnt.getKey(), innerHashMap);
                }

            }
            }
        }//synchronize innerhashmap
        }


        System.out.println(MyConstants.cliListUpdateList + " <---> "+ MyConstants.cliList);

    }
}

我在这一行收到异常: innerEnt = (Entry) innerIterator.next(); 我尝试了Iterator类提供的remove方法。 但这也不是一件好事。

编辑

从Java文档中我很了解, if a thread modifies a collection directly while it is iterating over the collection with a fail-fast iterator, the iterator will throw this(ConcurrentModificationException) exception但我需要完全相同的功能。

可能无法完全解决您的问题,而不是innerHashMap.remove(innerEnt.getKey()); 您需要使用迭代器的remove方法innerIterator.remove();

您是否尝试过使用同步哈希图? Collections.synchronizedMap(new HashMap())或看看ConcurrentHashMap

暂无
暂无

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

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