在Java中通过值从Map中删除元素的最快方法是什么?

Sup*_*tux 35 java collections performance

在Java中通过值从Map中删除元素的最快方法是什么?

目前我正在使用:

    DomainObj valueToRemove = new DomainObj();
    String removalKey = null;

    for (Map.Entry<String, DomainObj> entry : map.entrySet()) {
        if (valueToRemove.equals(entry.getValue())) {
            removalKey = entry.getKey();
            break;
        }
    }

    if (removalKey != null) {
        map.remove(removalKey);
    }
Run Code Online (Sandbox Code Playgroud)

小智 73

正确而快速的单线实际上是:

while (map.values().remove(valueObject));
Run Code Online (Sandbox Code Playgroud)

有点奇怪,上面的大多数例子都假设它valueObject是独一无二的.


Kev*_*vin 26

如果不使用双向地图(公共集合谷歌集合都有它们),你就会陷入迭代地图的困境


Jar*_*evy 24

这是一线解决方案:

map.values().remove(valueToRemove);
Run Code Online (Sandbox Code Playgroud)

这可能比定义自己的迭代器更快,因为JDK集合代码已经过显着优化.

正如其他人所提到的,bimap将有更快的值删除,但它需要更多的内存并且需要更长的时间来填充.此外,bimap仅在值唯一时才有效,这可能是您的代码中的情况,也可能不是.

  • 但是,如果map中两次出现valueToRemove,那么此代码不会只删除一个值,而不是两个值吗? (2认同)

ahl*_*hll 12

map.values().removeAll(Collections.singleton(null));
Run Code Online (Sandbox Code Playgroud)

参考 如何从HashMap <String,String>过滤"Null"值?,我们可以为java 8做以下事情:

map.values().removeIf(valueToRemove::equals);
Run Code Online (Sandbox Code Playgroud)


Tom*_*ine 11

如果你没有反向映射,我会选择迭代器.

DomainObj valueToRemove = new DomainObj();

for (
    Iterator<Map.Entry<String, DomainObj>> iter = map.entrySet().iterator();
    iter.hasNext();
) {
    Map.Entry<String, DomainObj> entry = iter.next();
    if (valueToRemove.equals(entry.getValue())) {
        iter.remove();
        break; // if only want to remove first match.
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 同意.我要提到的唯一另一件事是,如果您需要经常删除值,请确保Map是您应该为场景使用的实际数据结构. (4认同)

小智 7

您始终可以使用值集合,因为对该集合所做的任何更改都将导致更改反映在地图中.因此,如果您要调用Map.values().remove(valueToRemove)应该可以工作 - 虽然我不确定您是否会看到比使用该循环更好的性能.一种想法是扩展或覆盖map类,这样后备集合总是按值排序 - 这将使您能够对值进行二进制搜索,这可能更快.

编辑:这与Alcon的答案基本相同,除了我认为他的工作没有用,因为entrySet仍然按键排序 - 在这种情况下你不能用值调用.remove().

这也假设该值应该是唯一的,或者您也希望从Map中删除任何重复项.


Nic*_*ico 6

我会用这个

 Map x = new HashMap();
x.put(1, "value1");
x.put(2, "value2");
x.put(3, "value3");
x.put(4, "value4");
x.put(5, "value5");
x.put(6, "value6");

x.values().remove("value4");
Run Code Online (Sandbox Code Playgroud)

编辑:因为对象由"指针"引用而不是由值引用.

ñ