带有Map和Hashtable的ConcurrentModification异常

Gun*_*hah 1 java collections exception

在我的应用程序中,我使用了Map来存储POJO对象.根据要求,我需要迭代Map的keySet并删除不需要任何修改的对象.

考虑下面的代码..

 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);
       }
  }

 }
Run Code Online (Sandbox Code Playgroud)

这里在上面的代码中,当我尝试在删除对象后获取User对象时,我收到ConcurrentModificationException.

谁能告诉我为什么会发生?

我没有使用多线程.所以无法理解,从哪里生成ConCurrentModification Exception.

即使我尝试使用HashMap和Hashtable,但问题仍然存在.

谢谢,Gunjan.

Roh*_*ain 9

从它生成ConCurrentModification异常的地方.

它来自于您尝试从Map迭代时删除元素的行KeySet.

if(!user.isActive()){
     removeUser.remove(key);  // This is the problem
}
Run Code Online (Sandbox Code Playgroud)

你不应该这样做.如果要修改CollectionMap,请使用iterator.


看到这个非常好的帖子 - 高效 - 等同于删除元素 - 迭代 - 集合,解释了在修改迭代的集合时可能出现的问题.


这是一个简单的代码,解释了如何在这里使用它: -

    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);
Run Code Online (Sandbox Code Playgroud)

输出: -

{a=1}
Run Code Online (Sandbox Code Playgroud)


Pet*_*rey 5

如果您使用 ConcurrentHashMap 它不会产生 ConcurrentModificationException。

更通用的解决方案是使用迭代器来执行remove()。

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

注意:您不需要,keySet()因为您只对values()