[英]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.