这里有一些问题,如何获得与给定值相关联的Map
s键,答案指向谷歌集合(用于双向映射)或本质上说"循环它"。
我最近注意到Map接口有一个boolean containsValue(Object value)
方法,"对于大多数Map
接口的实现,可能需要映射大小的时间线性",并且AbstractMap
中的实现确实在entrySet()
上迭代。
在Map
中包含containsValue
而不包含Collection<V> getKeysForValue(Object)
的设计决策的原因是什么?我可以理解为什么一个人会忽略这两者,或者包括这两者,但如果有一个,为什么不包括另一个呢?
我想到的一件事是,它需要任何Map实现知道关于返回值的集合实现,但这实际上不是一个很好的理由,因为Collection<V> values()
方法也返回一个集合(AbstractMap
的情况下一个匿名new AbstractCollection<V>()
)。
有一些集合支持这一点,但它们通常涉及到维护反向查找映射,这比相对简单的一对一映射更昂贵。因此,这种支持可能会使所有地图的更新成本增加一倍以上。
另一个问题是泛化。键必须实现hashCode和equals(对于散列映射)或comparable(对于排序映射)值不必实现任何使构造广义反向查找不可能的东西,或者它对不太可能需要的值施加额外的要求。
map可以返回自1.2以来的键和值的Collection
,因此查找值是微不足道的:public Object containsValue(Object v) {return values().contains(v);}
此方法使用values()
和contains()
的本地优化,用于Map
的任何实现,但在大多数情况下可能很慢…
您正在寻找的getKeysForValue(Object)
不是微不足道的。它需要一个特定的算法,这个算法不能做得足够通用,它必须针对Map
的每个实现进行优化。
这可能是原因,或者只是因为Collection API充满了这种小漏洞…