在Javadocs中,映射接口具有用于containsKey(Object key)
、containsValue(Object value)
和get(Object key)
的方法。那么为什么没有getKey(Object value)
方法呢?一旦您有了一个方法来确定Map是否包含该值,为什么不也返回它呢?
我知道Map可以包含多个任意值,但也许该方法可以返回值的第一个实例。
发布于 2020-09-15 05:07:25
让我们以与使用联系人列表相同的方式使用java.util.Map
的实现,无论是在工作中还是在手机上。
例如,假设您想要找到您的朋友John Smith的电话号码,这样您就可以给他打电话。您可以按名字或姓氏进行搜索。
然而,Java在映射上的限制是,键在所有键中必须是惟一的,因此,如果您知道John Smith和John Doe,那么最后一个插入到映射中的人将“获胜”,并且您将丢失John Smith的数据。默默地。
如果您按姓氏插入(例如Smith),然后将您认识的所有Smith的值放入一个列表(John、Jane、William、Robert、Emmett),您将能够高效且安全地找到您要查找的内容,而不会有损坏您的联系人列表的风险。
不能按值搜索的原因是,a值在存储在key-value pair data structure中时没有显式保证的唯一性。即使是被吹捧为问题“解决方案”的Guava的BiMap
,仍然受到键和值之间唯一性的限制,这不是您想要的。更糟糕的是,拥有一个Map<List<String>, String>
的结构将是一场噩梦,主要是因为密钥可以改变,它是而不是任何人想要的。
如果您希望能够在给定一个值的情况下获得一个键,那么您别无选择,只能迭代数据结构的整个内容,这(谢天谢地,或者可怕地--请随意选择)正是Map.Entry<K, V>
提供的功能--一个可迭代的条目集,这样您就可以对映射中的每个元素进行自己的检查。
发布于 2020-09-15 04:45:00
Java接口设计用于高效地按键查找值。
最常用的实现之一是HashMap
,它将值放入存储桶中,并提供常量时间查找(假设值在存储桶中分布良好)。这意味着查找键的速度非常快-您可以在固定时间内对键进行散列,几乎可以立即查看是否有匹配值。但是,为了检查值的存在,您需要遍历所有的值。
另一个常见的实现是TreeMap
,在某些情况下,它可能比HashMap
更好,因为在这种情况下,可以很容易地对键进行排序。树的分支允许快速(尽管是log(n)
,而不是恒定时间)查找键。但是,同样,查找这些值需要遍历树的每个节点,直到找到一个值。
如果您需要这种从键到值或从值到键的查找,您应该使用BiMap
,它基本上是两个合并到一个对象中的映射-一个正向映射和一个反向映射。谷歌的Guava库has one,我以前用过。
更好的问题应该是“既然containsValue
方法对于大多数实现都是低效的,那么为什么Java Map
接口还要提供这种方法呢?”但我认为这可能是离题的--你可以考虑在Computer Science上问它。
发布于 2020-09-15 05:31:46
Java集合框架并没有实现理论上可以用所提供的类实现的所有特性--可能需要在特定的应用程序中添加一些特性。对于为什么选择一组特性而不是另一组特性,没有明确的答案--只有框架的原始设计者知道这一点。
然而,在这种情况下,似乎可以推测提供反向(value->key)查找将是一个坏主意,至少有两个原因。首先,与正向(key->value)查找相比,开发人员并不清楚它的效率必然较低。如果你真的必须使用迭代来实现它,那么它很快就会变得显而易见。
其次,尽管OP说反向查找方法可能会在多个键映射到相同值的情况下返回“第一个”匹配值,但在映射中确实没有“第一个”的可靠概念。
不过,归根结底,这都是猜测。
https://stackoverflow.com/questions/63891412
复制相似问题