2015-10-12 29 views
5

有兩張地圖,我試圖將它們合併成一張地圖(finalResp)。合併地圖並修改值

Map<String, String[]> map1 = new HashMap<>(); 
Map<String, String> map2 = new HashMap<>(); 

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

解決方案 - 前期的Java 8 - 實現象下面這樣:

for (Map.Entry<String, String[]> entry : map1.entrySet()) { 
    if (map2.containsKey(entry.getKey())) { 
     String newValue = changetoAnother(map1.get(entry.getKey()), map2.get(entry.getKey())); 
     finalResp.put(entry.getKey(), newValue); 
    } 
} 

使用Java 8,我被困在此:

HashMap<String, String> map3 = new HashMap<>(map2); 
map1.forEach((k, v) -> map3.merge(k, v, (i, j) -> mergeValue(i, j))); 

如何檢查如果地圖2鍵在地圖1中不存在並修改值?

回答

4

一種可能的方式是濾除不需要的元素(不包含在map2),結果收集到一個新地圖:

Map<String, String> finalResp = 
    map1.entrySet().stream().filter(e -> map2.containsKey(e.getKey())) 
          .collect(Collectors.toMap(
           Entry::getKey, 
           e -> changetoAnother(e.getValue(), map2.get(e.getKey())) 
          )); 

另一種方式是創建的map2副本,保留了所有按鍵這個Map也包含在map1鍵中,最後通過應用功能changetoAnother替換所有值。

Map<String, String> result = new HashMap<>(map2); 
result.keySet().retainAll(map1.keySet()); 
result.replaceAll((k, v) -> changetoAnother(map1.get(k), v)); 

注意,第一個解決方案的優點是,它可以很容易地推廣到任意兩個地圖的工作:

private <K, V, V1, V2> Map<K, V> merge(Map<K, V1> map1, Map<K, V2> map2, BiFunction<V1, V2, V> mergeFunction) { 
    return map1.entrySet().stream() 
          .filter(e -> map2.containsKey(e.getKey())) 
          .collect(Collectors.toMap(
           Entry::getKey, 
           e -> mergeFunction.apply(e.getValue(), map2.get(e.getKey())) 
         )); 
} 

Map<String, String> finalResp = merge(map1, map2, (v1, v2) -> changetoAnother(v1, v2)); 
+0

太好了!謝謝,但是當我在我的代碼中使用時,得到一個編譯器警告:「在封閉範圍內定義的局部變量map2必須是最終的或有效的最終結果」。在我的代碼中,像這樣獲取map2的值,Map map2 = getRespItemMap(response); – Umar

+0

使用廣義方法後,錯誤消失了。 finalResp = merge(map1,map2,(v1,v2) - > changetoAnother(v1,v2)); – Umar