繁体   English   中英

为什么没有方法可以在 Java Map 中返回给定值的键?

[英]Why is there no method for returning a Key given a Value in a Java Map?

Javadocs 中, Map 接口具有containsKey(Object key)containsValue(Object value)get(Object key) 为什么没有方法getKey(Object value) 一旦有了查找 Map 是否包含 Value 的方法,为什么还不能返回它呢?
我知道 Map 可能包含多个任何值,但也许该方法可以返回该值的第一个实例。

让我们以与使用联系人列表相同的方式使用java.util.Map的实现,无论是在工作中还是在手机上。

例如,假设您想找到您朋友 John Smith 的电话号码,以便您可以给他打电话。 您将得到无论是名字姓氏搜索的机会。

但是,Java 对映射的限制是所有键中的键必须是唯一的,因此,如果您知道一个 John Smith 和一个 John Doe,那么您插入到映射中的最后一个人将“获胜”,而您将输约翰史密斯的数据。 默默。

如果您改为按姓氏(例如 Smith)插入,然后将您认识的所有 Smiths 的值放入一个列表(John、Jane、William、Robert、Emmett),您将能够找到您要查找的内容既高效安全,而不会损坏您的联系人列表。


不能按值搜索的原因是,当值存储在键值对数据结构中时,没有明确的唯一性保证 即使 Guava 的BiMap被吹捧为您的问题的“解决方案”,仍然受到键值唯一性的限制,这不是您想要的。 更糟糕的是,拥有Map<List<String>, String>结构将是一场噩梦,主要是因为该键可以更改,而这根本不是任何人想要的

如果您希望能够获得给定值的键,那么您别无选择,只能迭代数据结构的全部内容,这(谢天谢地,或者可怕 - 选择)正是Map.Entry<K, V>提供 - 一个可迭代的条目集,以便您可以对地图中的每个元素进行自己的检查。

Java Map接口旨在通过键有效地查找值

最常用的实现之一是HashMap ,它将值放入桶中并提供恒定时间查找(假设值在桶中分布良好)。 这意味着查找键的速度非常快——您可以在恒定时间内对键进行散列,并且几乎可以立即查看是否存在匹配值。 但是,为了检查值是否存在,您需要遍历所有值。

另一种常见的实现是TreeMap ,在某些情况下,您的键可以轻松排序,它可能比HashMap更好。 树的分支允许快速(虽然log(n) ,而不是恒定时间)键查找。 然而,再次查找值需要遍历树的每个节点,直到找到一个值。

如果您需要这种可以从 Key 到 Value 或 Value 到 Key 的查找,您应该使用BiMap ,它基本上是两个映射到一个对象中 - 一个正向映射和一个反向映射。 谷歌的番石榴库有一个我过去用过的。


更好的问题是“如果此方法对于大多数实现来说效率低下,为什么 Java Map接口提供containsValue方法?” 但我希望这可能与 SO 无关 - 您可以考虑在Computer Science 中询问。

Java 集合框架并没有实现理论上可以用所提供的类实现的所有功能——某些功能可能需要添加到特定应用程序中。 对于为什么选择一组功能而不是另一组功能,没有明确的正确答案——只有框架的原始设计者知道这一点。

但是,在这种情况下,至少有两个原因可以推测提供反向(值->键)查找将是一个坏主意,这似乎是合理的。 首先,对于开发人员来说,与正向(键-> 值)查找相比,它必然是低效的,这一点并不明显。 如果您实际上必须使用迭代来实现它,这将很快变得显而易见。

其次,尽管 OP 表示在多个键映射到相同值的情况下,反向查找方法可能会返回“第一个”匹配值,但映射中确实没有“第一个”的强大概念。

不过,归根结底,这都是猜测。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM