2016-03-01 77 views
5
Map<String, String> map1 = new HashMap<>(); 
map1.put("k1", "v1"); 
map1.put("k2", "v2"); 
map1.put("k3", "v3"); 

Map<String, String> map2 = new HashMap<>(); 
map2.put("v1", "val1"); 
map2.put("v2", "val2"); 
map2.put("v3", "vav3"); 

我想更新MAP1使之具有條目的值的基礎上:更新價值觀地圖等地圖中的Java

  • 「K1」, 「VAL1」
  • 「K2」, 「值2」,
  • 「K3」, 「VAL3」

我的解決辦法:

for (Map.Entry<String, String> entry : map1.entrySet()) { 
    map1.put(entry.getKey(), map2.get(entry.getValue())); 
} 

有沒有更好的方法來做到這一點?

編輯:我使用的Java 7,但想知道是否有在Java中8

+0

不是真的,沒有 - 雖然看起來你應該做'map3.put'而不是'map1.put'? –

+1

is this java 8?在這種情況下,流可以幫助你。 – njzk2

+0

另外,當填充'map2'時,你應該做'map2.put'而不是'map1.put'。 – Atri

回答

3

什麼更好的方法與Java 8開始,你可以有

map1.replaceAll((k, v) -> map2.get(v)); 

replaceAll(function)將替換地圖map1中的所有值以及應用給定函數的結果。在這種情況下,函數只需從map2中檢索值。

請注意,此解決方案與初始代碼具有相同的問題:如果map2沒有相應的映射,則會返回null。在這種情況下,您可能需要撥打getOrDefault以獲得默認值。

public static void main(String[] args) { 
    Map<String, String> map1 = new HashMap<>(); 
    map1.put("k1", "v1"); 
    map1.put("k2", "v2"); 
    map1.put("k3", "v3"); 

    Map<String, String> map2 = new HashMap<>(); 
    map2.put("v1", "val1"); 
    map2.put("v2", "val2"); 
    map2.put("v3", "val3"); 

    map1.replaceAll((k, v) -> map2.get(v)); 

    System.out.println(map1); // prints "{k1=val1, k2=val2, k3=val3}" 
} 
+0

對Java 7有任何評論? –

+0

@devツ說實話,除了我提到的情況(地圖沒有相應的關鍵字)之外,還沒有真正的改進空間。沒問題。 – Tunaki

0

在Java中8,你可以這樣寫:

map1.entrySet() 
    .stream() 
    .map(entry -> new SimpleEntry(entry.getKey(), map2.get(entry.getValue()))) 
    .collect(Collectors.toMap(entry -> entry.getKey(), entry.getValue())); 

不是最好的事情,雖然,但仍然是一個非突變的解決方案。

+0

在Java7中有更好的方法嗎? –

1

對於Java 7來說,除了可以做的事之外,您已經可以以最好的方式做到這一點。

我添加了這個答案作爲參考,表明對於使用Java 8中的Lambda表達式的情況,這將更糟。看到這個例子:

public static void main(String[] args) { 
    Map<String, String> map1 = new HashMap<>(); 
    final Map<String, String> map2 = new HashMap<>(); 

    for (int i=0; i<100000; i++){ 
     map1.put("k"+i, "v"+i); 
     map2.put("v"+i, "val"+i); 
    } 

    long time; 
    long prev_time = System.currentTimeMillis(); 
    for (Map.Entry<String, String> entry : map1.entrySet()) { 
     map1.put(entry.getKey(), map2.get(entry.getValue())); 
    } 
    time = System.currentTimeMillis() - prev_time; 
    System.out.println("Time after for loop " + time); 


    map1 = new HashMap<>(); 
    for (int i=0; i<100000; i++){ 
     map1.put("k"+i, "v"+i); 
    } 

    prev_time = System.currentTimeMillis(); 
    map1.replaceAll((k, v) -> map2.get(v)); 
    time = System.currentTimeMillis() - prev_time; 
    System.out.println("Time after for loop " + time); 
} 

這種情況的輸出將是:

Time after for loop 40 
Time after for loop 100 

第二回路是可變的,但總是比第一個更大。

我不是拉姆達專家,但我想有更多的與它進行處理比第一個方案

一遍又一遍你運行這個測試案例的平原「的foreach」將獲得拉姆達幾乎總是是第一次「foreach」案件的兩倍。