Reputation: 5168
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.
Upvotes: 2
Views: 4480
Reputation: 46428
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.
}
Upvotes: 2
Reputation: 213351
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}
Upvotes: 11
Reputation: 533750
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()
Upvotes: 5