我正在做:

for (Object key : map.keySet())
    if (something)
        map.remove(key);

它抛出了一个ConcurrentModificationException,所以我把它改为:

for (Object key : new ArrayList<Object>(map.keySet()))
    if (something)
        map.remove(key);

这个过程以及修改映射的任何其他过程都在同步块中。

有没有更好的解决方案?


当前回答

ConcurrentHashMap

你可以使用java.util.concurrent.ConcurrentHashMap。

它实现了ConcurrentMap(扩展了Map接口)。

例如:

Map<Object, Content> map = new ConcurrentHashMap<Object, Content>();

for (Object key : map.keySet()) {
    if (something) {
        map.remove(key);
    }
}

这种方法不会影响代码。只是映射类型不同。

其他回答

从Java 8开始,你可以这样做:

map.entrySet().removeIf(e -> <boolean expression>);

entrySet()

集合是由映射支持的,所以对映射的更改会反映在集合中,反之亦然

Set s=map.entrySet();
Iterator iter = s.iterator();

while (iter.hasNext()) {
    Map.Entry entry =(Map.Entry)iter.next();

    if("value you need to remove".equals(entry.getKey())) {
         map.remove();
    }
}

使用真正的迭代器。

Iterator<Object> it = map.keySet().iterator();

while (it.hasNext())
{
  it.next();
  if (something)
    it.remove();
 }

实际上,您可能需要遍历entrySet()而不是keySet()才能使其工作。

在遍历映射时,必须使用Iterator来安全地删除元素。

下面是一个在for循环中使用迭代器删除条目的代码示例。

Map<String, String> map = new HashMap<String, String>() {
  {
    put("test", "test123");
    put("test2", "test456");
  }
};

for(Iterator<Map.Entry<String, String>> it = map.entrySet().iterator(); it.hasNext(); ) {
    Map.Entry<String, String> entry = it.next();
    if(entry.getKey().equals("test")) {
        it.remove();
    }
}