ConcurrentModification Exception with Map and Hashtable

邮差的信 提交于 2020-02-02 13:15:30

问题


In my application I have used a Map to store POJO objects. As per the requirement I need to iterate over the keySet of the Map and remove objects which dont need any modification.

Conside the code below:

 public void remove(Map<String,User> removeUser){
  Set<String> keySet = removeUser.keySey();
  User user = null;

  for(String key : keySet){
      user = (user) removeUser.get(key);

       if(!user.isActive()){
                removeUser.remove(key);
       }
  }

 }

Here in above code, I am getting ConcurrentModificationException when I try to fetch User object after Object removal.

Can anyone tell me why it's happening?

I have not used multi threading.So not able to understand, from where it generated ConCurrentModification Exception.

Even I tried with HashMap and Hashtable, but the problem still exist.


回答1:


from where it generated ConCurrentModification Exception.

It came from the line where you are trying to remove the element from your Map while iterating over its KeySet.

if(!user.isActive()){
     removeUser.remove(key);  // This is the problem
}

You should not do that. If you want to modify your Collection or Map, use an iterator.


See this very nice post - efficient-equivalent-for-removing-elements-while-iterating-the-collection explaining the problems that can come while modifying the collection you iterate upon.


Here's a simple code explaining how you can use it here: -

    Map<String, Integer> map = new HashMap<String, Integer>() {
        {
            put("a", 1);
            put("b", 2);
            put("c", 3);
        }
    };

    Iterator<String> iterate = map.keySet().iterator();

    while  (iterate.hasNext()) {
        int i = map.get(iterate.next());

        if(i > 1) {
            iterate.remove();
        }
    }

    System.out.println(map);

OUTPUT: -

{a=1}



回答2:


If you use ConcurrentHashMap it won't produce a ConcurrentModificationException.

The more general solution is to use the Iterator to do the remove().

public void removeInactiveUsers(Map<String, User> map) {
    for (Iterator<User> iter = map.values().iterator(); iter.hasNext(); ) 
        if (!user.isActive())
            iter.remove();
}

Note: you don't need the keySet() as you are only interested in the values()




回答3:


use an iterator to iterate over your Set and use iterator.remove(), you cant remove elements from your collection while iterating over it.you'd get a ConcurrentModification Exception

root cause of your Exception is here:

        removeUser.remove(key);

iterate over your set like this, using an iterator.

Iterator<String> itr = keySet .iterator();
while(itr.hasNext){
   String s = itr.next();
   itr.remove(); // to remove the current element.
 }


来源:https://stackoverflow.com/questions/13453217/concurrentmodification-exception-with-map-and-hashtable

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!