簡體   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