2016-04-15 81 views
0

這可能是一個基本的Java問題,但我不知何故無法找到正確的關鍵字到谷歌正確的解決方案。Java:編寫泛型HashMap合併方法的正確方法是什麼?

我有幾對HashMap對象,我需要以直接的方式合併每個相應的對:如果兩個鍵匹配,將兩個值相加並將總和存儲在第一個地圖中。所以我可能是這樣的:

HashMap<String,Double> mapSD1, mapSD2; 
HashMap<String,Integer> mapSI1, mapSI2; 
HashMap<MyClassA,Float> mapCF1, mapCF2; 

什麼是寫一個通用的mergeMaps方法,可以合併所有這些類型的,而不是有3種每種類型或多或少相同方法的正確方法嗎?

+0

作爲一個最佳實踐,你應該使用'Map <>'而不是'HashMap <>'來持有對'HashMap <>'實例的引用。這通常是真實的 - 在創建集合時使用特定的實現類型,並使用接口類型來保存它們的引用。如果您在使用的類型中存在不必要的特定情況,那麼它會減少代碼的可維護性 - 如果您應該選擇不同的'Map <>實現,您將被迫重構。 –

回答

0

沒有通用的方法來添加不同類型的數字。您將不得不告訴方法如何將值添加到Float值,兩個Integer值等。

由於您使用的是Java 7,因此您必須先準備一些基礎。您可以創建以下接口:

public interface BinaryOperator<T> { 

    T apply(T t1, T t2); 
} 

然後,你可以這樣做:

private static final BinaryOperator<Float> ADD_FLOATS = new BinaryOperator<Float>() { 
    @Override 
    public Float apply(Float t1, Float t2) { 
     return t1 + t2; 
    } 
}; 

public static <K, V> void merge(Map<K, V> map1, Map<K, V> map2, BinaryOperator<V> op) { 
    for (Map.Entry<K, V> e : map2.entrySet()) { 
     V val = map1.get(e.getKey()); 
     if (val == null) { 
      map1.put(e.getKey(), e.getValue()); 
     } else { 
      map1.put(e.getKey(), op.apply(val, e.getValue())); 
     } 
    } 
} 

public static void main(String[] args) { 
    Map<String, Float> map = new HashMap<>(); 
    map.put("A", 1.2F); 
    map.put("B", 3.4F); 
    Map<String, Float> map2 = new HashMap<>(); 
    map2.put("B", 5.6F); 
    map2.put("C", 7.8F); 
    merge(map, map2, ADD_FLOATS); 
    System.out.println(map); // prints {A=1.2, B=9.0, C=7.8} 
} 

當您升級到Java 8,你將能夠擺脫BinaryOperator(它已經存在),並且將有無需創建ADD_FLOATS。你可以做

merge(map, map2, Float::sum); 
+0

不幸的是,我仍然在使用Java 7.但無論如何謝謝 –

+0

@IZ我已經完全重寫了我的答案。這可能是更多你在找什麼? –