为什么Java';s映射接口有一个containsValue(Object)方法,但没有值->;钥匙查找?

为什么Java';s映射接口有一个containsValue(Object)方法,但没有值->;钥匙查找?,java,map,Java,Map,这里有一些问题,如何获得与给定值关联的Maps键,答案指向google集合(对于双向地图)或本质上说是“在它上面循环” 我最近注意到Map接口有一个boolean containsValue(Object value)方法,“对于Map接口的大多数实现,可能需要映射大小的时间线性,AbstractMap中的实现确实在entrySet()上迭代 设计决策将containsValue包含在映射中,但不包含集合getKeysForValue(对象)的原因是什么?我可以理解为什么一个会同时省略这两个,或

这里有一些问题,如何获得与给定值关联的
Map
s键,答案指向google集合(对于双向地图)或本质上说是“在它上面循环”

我最近注意到Map接口有一个
boolean containsValue(Object value)
方法,“对于
Map
接口的大多数实现,可能需要映射大小的时间线性,
AbstractMap
中的实现确实在
entrySet()
上迭代

设计决策将
containsValue
包含在
映射中,但不包含
集合getKeysForValue(对象)
的原因是什么?我可以理解为什么一个会同时省略这两个,或者同时包含这两个,但是如果有一个,为什么不包括另一个呢


我想到的一件事是,任何映射实现都需要知道返回值的集合实现,但这实际上不是一个好的理由,因为
Collection values()
方法也会返回一个集合(在
AbstractMap
的情况下,是一个匿名的
new AbstractCollection()
).

自1.2版以来,映射可以返回其键和值的
集合,因此查找值非常简单:
公共对象containsValue(Object v){return values().contains(v);}
此方法使用
值()
包含()
中的本机优化来实现
映射,但在大多数情况下,速度可能会很慢

您要查找的
getKeysForValue(对象)
并非微不足道。它需要一个特定的算法,并且该算法不能变得足够通用,必须针对
Map
的每个实现对其进行优化


这可能是原因,也可能仅仅是因为集合API充满了这种小漏洞……

有支持这一点的集合,但它们通常涉及维护反向查找映射,这比相对简单的一对一映射更昂贵。因此,支持这一点可能会使所有地图的更新成本增加一倍以上


另一个问题是泛化。键必须实现hashCode和equals(对于哈希映射)或Compariable(对于排序映射)值不必实现任何使构造通用反向查找变得不可能的东西,或者对不太可能需要的值提出额外要求。

好吧,我真的很喜欢第2段中的参数。但需要实现equals的问题也是现有方法
containsValue(Object)
的问题。它仅在value类实现适当的equals方法时有用。现在我们回到问题上来。。。我认为
包含值(对象)
是一个API意外事件,但由于兼容性原因无法删除。你怎么看?我认为
containsValue
的价值值得怀疑,如果你真的需要它,你可以为(V value:map.values())做以下
,如果(value.equals(loopup))…
我会说它与极简设计方法不一致。有趣的是,
AbstractMap.values()
返回一个
集合
,该集合的
包含(对象v)
方法只返回
抽象映射。这个.containsValue(v)
,而
containsValue本身迭代
entrySet()
。不知何故,.NET中不存在问题:)