从散列映射中删除给定值的所有项

Ant*_*ebb 18 java hashmap

所以我有一个如下所示的java hashmap:

hMap.put("1", "One");
hMap.put("2", "Two");
hMap.put("3", "Two");
Run Code Online (Sandbox Code Playgroud)

我想删除值为"Two"的所有项目

如果我这样做:

hmap.values().remove("Two");
Run Code Online (Sandbox Code Playgroud)

只删除了第一个,我想将它们全部删除,怎么办呢?

Kev*_*ion 45

hmap.values().removeAll(Collections.singleton("Two"));

编辑:这个简洁方法的(显着)缺点是你基本上被迫评论它,说类似的东西

// remove("Two") would only remove the first one

否则,一些善意的工程师会在某一天尝试为你简化并打破它.这种情况发生了...有时好心的做事甚至是未来你!


Gre*_*ers 22

在Java 8中

hmap.values().removeIf(val -> "Two".equals(val));
Run Code Online (Sandbox Code Playgroud)


Ron*_*Ron 15

for (Iterator<Map.Entry<String,String>> it = hMap.entrySet().iterator(); it.hasNext();) {
 Map.Entry<String,String> e = it.next();
 if ("Two".equals(e.getValue())) {
  it.remove();
 }
}
Run Code Online (Sandbox Code Playgroud)

  • 这个解决方案当然有效,但凯文的答案更简洁. (2认同)

sgt*_*oyd 10

您可以使用,while( hmap.values().remove("Two") );因为true如果由于调用而更改了集合,则删除调用将返回.

  • @Anthony:Kevin正在谈论最糟糕的表现.请参阅http://en.wikipedia.org/wiki/Big_O_notation#Orders_of_common_functions要在没有(很多)数学的情况下回答 - 此解决方案将遍历地图元素n + 1次,其中n是要删除的值的数量.另一种解决方案,比如凯文或罗恩,只会迭代地图中的值一次.如果您在非常大的地图上操作,使用此解决方案的方法的运行时会慢得多. (5认同)

Jon*_*oth 6

(更新了已删除值的记录解决方案)

此解决方案使用google-collections库[ LINK ]

import static com.google.common.collect.Maps.filterValues;
import static com.google.common.base.Predicates.equalTo;

...

Map<String, String> removedValues = filterValues(hMap, equalTo("Two"));      
System.out.println(removedValues); //Log Removed Values
removedValues.clear(); //Removes from original map, since this is a view.
Run Code Online (Sandbox Code Playgroud)

注 - 此解决方案利用了filterValues调用返回的Map是原始HashMap中元素的视图这一事实.这允许我们检查它们并注销已删除的键,然后通过简单的clear()调用将它们从原始地图中删除.

您可能有理由不想在项目中使用google-collections库,但如果不这样做,我建议您查看它.