ConcurrentModification exception with Map and Hashtable

In my application, I used a map to store POJOs. As per requirement, I need to iterate over a set of map keys and remove objects that don't need any changes.

Consider 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 the above code, I am getting a ConcurrentModificationException when trying to retrieve a user object after deleting the object.

Can anyone tell me why this is happening?

I have not used multithreading. So I can't figure out where it was throwing the ConCurrentModification exception from.

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

+1


source to share


3 answers


from where it threw a ConCurrentModification exception.

It was coming from the line where you are trying to remove the item from Map

, iterating over it KeySet

.

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

      

You shouldn't be doing this. If you want to change your Collection

or Map

, use iterator

.


Take a look at this very nice post - efficient-equivalent-for-removing-elements-while-iterating-the-collection , which explains the problems that can arise when changing the collection you are iterating into.




Here is 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}

      

+9


source


If you are using ConcurrentHashMap, it will not throw ConcurrentModificationException.

A more general solution is to use an Iterator to do 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 keySet()

it as you are only interested invalues()

+4


source


use an iterator to iterate over Set and use iterator.remove()

, you cannot remove items from a collection by iterating over it. you will get ConcurrentModification exception

root reason for your exception:

        removeUser.remove(key);

      

iterating over your set using this iterator.

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

      

+2


source







All Articles