how to merge more than one hashmaps also sum the values of same key in java

妖精的绣舞 提交于 2019-12-09 08:27:05

问题


ı am trying to merge more than one hashmaps also sum the values of same key, ı want to explain my problem with toy example as follows

    HashMap<String, Integer> m = new HashMap<>();
    HashMap<String, Integer> m2 = new HashMap<>();

    m.put("apple", 2);
    m.put("pear", 3);
    m2.put("apple", 9);
    m2.put("banana", 6);

ı tried putall

m.putAll(m2);

output is as follows {banana=6, apple=9, pear=3}

but its result is not true for this problem. ı want to output as

{banana=6, apple=11, pear=3}

how can ı get this result in java?


回答1:


If you are using Java 8, you can use the new merge method of Map.

m2.forEach((k, v) -> m.merge(k, v, (v1, v2) -> v1 + v2));



回答2:


This is a very nice use case for Java 8 streams. You can concatentate the streams of entries and then collect them in a new map:

Map<String, Integer> combinedMap = Stream.concat(m1.entrySet().stream(), m2.entrySet().stream())
    .collect(Collectors.groupingBy(Map.Entry::getKey,
             Collectors.summingInt(Map.Entry::getValue)));

There are lots of nice things about this solution, including being able to make it parallel, expanding to as many maps as you want and being able to trivial filter the maps if required. It also does not require the orginal maps to be mutable.




回答3:


This method should do it (in Java 5+)

public static <K> Map<K, Integer> mergeAndAdd(Map<K, Integer>... maps) {
    Map<K, Integer> result = new HashMap<>();
    for (Map<K, Integer> map : maps) {
        for (Map.Entry<K, Integer> entry : map.entrySet()) {
            K key = entry.getKey();
            Integer current = result.get(key);
            result.put(key, current == null ? entry.getValue() : entry.getValue() + current);
        }
    }
    return result;
}



回答4:


Here's my quick and dirty implementation:

import java.util.HashMap;
import java.util.Map;

public class MapMerger {

    public static void main(String[] args) {
        HashMap<String, Integer> m = new HashMap<>();
        HashMap<String, Integer> m2 = new HashMap<>();

        m.put("apple", 2);
        m.put("pear", 3);
        m2.put("apple", 9);
        m2.put("banana", 6);

        final Map<String, Integer> result = (new MapMerger()).mergeSumOfMaps(m, m2);
        System.out.println(result);
    }

    public Map<String, Integer> mergeSumOfMaps(Map<String, Integer>... maps) {
        final Map<String, Integer> resultMap = new HashMap<>();
        for (final Map<String, Integer> map : maps) {
            for (final String key : map.keySet()) {
                final int value;
                if (resultMap.containsKey(key)) {
                    final int existingValue = resultMap.get(key);
                    value = map.get(key) + existingValue;
                }
                else {
                    value = map.get(key);
                }
                resultMap.put(key, value);
            }
        }
        return resultMap;
    }
}

Output:

{banana=6, apple=11, pear=3}

There are some things you should do (like null checking), and I'm not sure if it's the fastest. Also, this is specific to integers. I attempted to make one using generics of the Number class, but you'd need this method for each type (byte, int, short, longer, etc)




回答5:


ı improve Lucas Ross's code. in stead of enter map by one by in function ı give all maps one times to function with arraylist of hashmap like that

    public HashMap<String, Integer> mergeAndAdd(ArrayList<HashMap<String, Integer>> maplist) {
    HashMap<String, Integer> result = new HashMap<>();
    for (HashMap<String, Integer> map : maplist) {
        for (Map.Entry<String, Integer> entry : map.entrySet()) {
            String key = entry.getKey();
            Integer current = result.get(key);
            result.put(key, current == null ? entry.getValue() : entry.getValue() + current);
        }
    }
    return result;
}

}

it works too. thanks to everbody




回答6:


If the key exists, add to it's value. If not insert.

Here is a simple example which merges one map into another:

Foo oldVal = map.get(key);
if oldVal == null
{
   map2.put(key, newVal);
}
else
{
   map2.put(key, newVal + oldVal);
}

Obviously you have to loop over the first map so you can process all of it's entries but that's trivial.




回答7:


Something like this should work:

 for (Map.Entry<String, Integer> entry : map.entrySet()) {
    String map1_key = entry.getKey();
    int map1_value = entry.getValue();

    //check:
    if(map2.get(map1_key)!=null){
    int map2_value = map2.get(map1_key);
    //merge:
    map3.put(map1_key,map1_value+map2_value);
    }else{
    map3.put(map1_key,map1_value);
    }
}


  for (Map.Entry<String, Integer> entry2 : map2.entrySet()) {
        String map2_key = entry2.getKey();
        int map2_value = entry2.getValue();

        //check:
        if(map1.get(map2_key)!=null){
        int map1_value = map1.get(map2_key);
        //merge:
        map3.put(map2_key,map1_value+map2_value);
        }else{
        map3.put(map2_key,map2_value);
        }
    }



回答8:


Assume that you have many HashMaps: HashMap<String,Integer> map1, map2, map3;

Then you can use Java 8 streams:

List<Map<String,Integer>> mapList = Arrays.asList(map1, map2, map3);

Map<String,Integer> combinedMap = mapList.stream()
        .flatMap(map -> map.entrySet().stream())
        .collect(Collectors.groupingBy(Entry::getKey,
                Collectors.summingInt(Entry::getValue)));


来源:https://stackoverflow.com/questions/28866085/how-to-merge-more-than-one-hashmaps-also-sum-the-values-of-same-key-in-java

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!