简体   繁体   中英

Java: What's the right way of writing a generic HashMap merge method?

This is probably a basic Java question but I somehow can't find the right keywords to google for the right solution.

I have several pairs of HashMap objects and I need to merge each respective pair in a straightforward ways: if two keys match, add up the two values and store the sum in the first map. So I might have something like:

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

What is the right way of writing a generic mergeMaps methods that can merge all these types, instead of having 3 more or less identical methods for each type?

There is no generic way to add numbers of different types. You would have to tell the method how to add to Float values, two Integer values etc.

Since you are using Java 7, you will have to prepare some ground first. You could create the following interface:

public interface BinaryOperator<T> {

    T apply(T t1, T t2);
}

Then you could do:

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}
}

When you upgrade to Java 8 you will be able to get rid of BinaryOperator (it's already there), and there would be no need to create ADD_FLOATS . You will be able to just do

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM