2011-04-14 67 views
1

有什麼方法可以獲取與地圖中已知值關聯的鍵?通常情況下,你知道鑰匙,你想獲得價值,但我想做相反的事情,從價值到鑰匙。可能嗎?Java地圖,從值到鍵

+1

使價值的關鍵。是的,這就是Captian Obvious所說的,但它確實是除了在地圖上進行線性搜索之外的唯一途徑 - 就像拉里沃爾指出的那樣,試圖用一個裝滿的烏茲人來詛咒他人。 – delnan 2011-04-14 22:22:09

+0

[Java key - key map](http:// stackoverflow。com/questions/1680463/java-key-key-map)和[hashmap with reverse lookup](http://stackoverflow.com/questions/1670038/does-java-have-a-hashmap-with-reverse-lookup) – BalusC 2011-04-14 22:29:17

回答

2

是的,你必須遍歷在地圖中的值,然後存儲在列表中的每個關鍵:

for (Map.Entry<K,V> entry : map.entrySet()) { 
    V value = entry.getValue(); 
    if (value.equals(someTargetValue) { 
     // add key (entry.getKey()) to list 
    } 
} 

或者你可以使用一個bidirectional map,雖然做筆記:

這map強制實現了鍵和值之間存在1:1關係的限制,這意味着多個鍵無法映射到相同的值。

+4

雙向地圖應該可以工作。如果您不想使用額外的庫,只需將兩個映射與值鍵逆轉,這就是實現雙向映射的方式。 – 2011-04-14 22:27:27

+0

您所描述的雙向地圖只適用於數學身份。如果有兩個值指向同一個對象,則「反向」方向必須有兩個鍵,因此不是數學映射。也許這是一個很好的觀點,但是如果你的數據集有重複的值,那麼它就會有一個不同的世界。 – 2011-04-14 22:41:42

+0

@Edwin這是正確的,並在其網頁上的描述中指出:「此映射強制實現了鍵和值之間存在1:1關係的限制,這意味着多個鍵無法映射到相同的值。」這也是爲什麼我提供這兩種潛在的解決方案。我也會告訴你答案。 – 2011-04-14 22:55:14

0

一個地圖是不意味着反向映射是可能的數學項。也就是說,如果每個映射值都是唯一的,你可能會創建一個「反向」映射。當然,您必須將所有數據操作封裝在適當更新兩個地圖的方法中。

如果每個映射值不是唯一的,那麼你需要創建一個值的反向映射到按鍵的列表。

Map<Key, Value> normal; 
Map<Value, List<Key>> reverse; 

最後,如果您不關心快速訪問,您可以遍歷整個Map來查找值。既然你需要Value和Key,最好迭代Map.Entry項。

Value searchingFor = ...; 
Map<Key, Value> normal; 
List<Key> keys = new ArrayList<Key>(); 
for (Map.Entry<Key, Value> entry : normal.entrySet()) { 
    if (entry.getValue().equals(searchingFor)) { 
    keys.add(entry.getKey()); 
    } 
} 

您選擇使用的技術在很大程度上取決於是否更好地交換內存佔用速度。由於在值上執行散列操作,通常具有額外映射的速度更快,但會花費額外的內存。對Map.Entry進行循環較慢,但成本較低。

1

那麼,我不是Google Project LambdaJ的專家,但它肯定提供了一些很酷的選擇。

假如你有一個月的日子地圖:

month.put(1,"Monday"); 
month.put(2,"Tuesday"); 
month.put(3,"Wednesday"); 
... 

然後,我們可以很容易地達到你想要的東西是這樣的:

Set<Integer> result = with(month).retainValues(is("Friday")).keySet(); 

甚至幾更有趣的搜索像:

Set<Integer> result = with(month).retainValues(anyOf(is("Monday"),is("Friday"))).keySet();