2010-12-14 33 views
12

我已經知道如何以困難的方式做到這一點,並讓它工作 - 迭代條目並交換「手動」。但是我想知道,像這麼多任務一樣,這個問題可以用更優雅的方式解決。如何在一個優雅的地圖中交換密鑰和值

我已閱讀this post,遺憾的是它並不擁有優雅的解決方案。我也沒有可能使用任何花哨的Guava BiMaps或jdk之外的任何東西(項目堆棧已經定義)。

我可以假設我的映射是雙射,順便說一句:)

+3

增加一個額外的工具庫是不是真的改變UI框架,你使用會這是(比方說)改變着工程「棧」。我敦促你重新考慮你反對在所有可能的情況下使用番石榴。 – 2010-12-14 07:57:48

+0

所有你需要的是一個單一的循環與一條線是簡單和elegent。恕我直言。 Java不是一種功能性語言。 – 2010-12-14 08:07:06

+0

謝謝大家,所有那些重疊和簡潔的答案,真的很難選擇哪一個接受。我想我會和Aaron Digulla一起提供一個包裝解決方案。 – kostja 2010-12-14 08:22:21

回答

8

標準的API/Java運行時不提供雙向映射,所以唯一的解決辦法是遍歷所有條目和手動交換他們。

你可以做的是創建一個包裝類,其中包含兩個地圖,並在內部執行雙重put(),因此您可以快速獲得兩個數據視圖。

[編輯],由於開源的,你不必包括第三方庫,你可以簡單地複製你需要到自己的項目中的類。

3

地圖不像列表,這可以通過與尾交換頭部被逆轉。在地圖

對象有一個計算的位置,並使用該值作爲密鑰和密鑰作爲值將requiere重新計算存儲地方,essentialy建立另一個映射。沒有優雅的方式。

但是,有雙向映射。這些可能適合您的需求。我會重新考慮使用第三方庫。

2

有一些工作可以簡化到某一點,而不是更多。這可能就是其中之一!

如果你想要做的使用Java集合工作的API只有蠻力是要走的路 - 這將是快速的(除非集合類是巨大的),這將是代碼的一個明顯的部分。

20

如果您沒有選擇使用第三方庫,我不考慮下面的代碼這麼醜(雖然一些腳本語言中確實有這樣做的優雅的方式):

//map must be a bijection in order for this to work properly 
public static <K,V> HashMap<V,K> reverse(Map<K,V> map) { 
    HashMap<V,K> rev = new HashMap<V, K>(); 
    for(Map.Entry<K,V> entry : map.entrySet()) 
     rev.put(entry.getValue(), entry.getKey()); 
    return rev; 
} 
+0

謝謝,這個讓我想起了我自己的代碼:) – kostja 2010-12-14 08:17:39

14
Map<String, Integer> map = new HashMap<>(); 
Map<Integer, String> swapped = map.entrySet().stream().collect(Collectors.toMap(Map.Entry::getValue, Map.Entry::getKey)); 
+0

真棒解決方案。 – chandresh 2017-05-09 07:52:28

0

以提示回答 https://stackoverflow.com/a/42091477/8594421

這僅適用於,如果地圖是不是一個HashMap和不包含重複的值。

Map<String,String> newMap = oldMap.entrySet().stream().collect(Collectors.toMap(Map.Entry::getValue, Map.Entry::getKey)); 

拋出一個異常

java.lang.IllegalStateException:重複鍵

如果有值不止一次。

解決辦法:

HashMap<String,String> newMap = new HashMap<>(); 

for(Map.Entry<String,String> entry : oldMap.entrySet()) 
     newMap.put(entry.getValue(), entry.getKey()); 

// Add inverse to old one 
oldMap.putAll(newMap);