如何使用Java首选Java8合并多个映射和聚合值结果

时间:2016-07-21 17:14:24

标签: java dictionary hashmap java-8

假设我有多个N地图,其中包含> key:string val:Object

我想将所有这些合并到一个大地图中,并将它们的对象字段值相加:

例如:

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

/**
 * Created by vitaly on 21/07/2016.
 */
public class Merge {

    static Map<String, Container> map1 = new HashMap<>();
    static Map<String, Container> map2 = new HashMap<>();
    static Map<String, Container> map3 = new HashMap<>();


    public void initMaps() {
        map1.put("aaa", new Container(1, "title_aaa"));
        map1.put("bbb", new Container(4, "title_bbb"));

        map2.put("ccc", new Container(7, "title_ccc"));
        map2.put("aaa", new Container(10, "title_aaa"));

        map3.put("aaa", new Container(13, "title_aaa"));
        map3.put("bbb", new Container(16, "title_bbb"));
        ...
        mapN.put(...
    }

    class Container {
        public Container(int val1, String title) {
            this.val1 = val1;
            this.title = title;

        }

        int val1;
        String title;

    }

    public static void main(String[] args) {
        Merge.mergeMaps(map1, map2, map3);
    }

    public static Map<String, Container> mergeMaps(Map... maps) {
        /**
         * HOW create one merged map that sums the values
         */
// The result should be: 
        //map(aaa, {24,title_aaa )   //1+10+13
        //map(bbb, {20,title_ccc )   //4+16
        //map(ccc, {7,title_ccc )   //7
        return map;
    }
}

首选Java 8,但这并不重要:)

非常感谢!

2 个答案:

答案 0 :(得分:2)

流式传输不同的地图,将它们平面映射为一个。然后使用Container通过不同的值(aaa,bbb等)对它们进行排序。 然后再次对此结果进行流式处理,以创建具有求和值的新Collectors.toMap个对象。

最后,使用public static Map<String, Container> mergeMaps(Map<String, Container>... maps) { Map<String, Container> map = Arrays.stream(maps) .flatMap(x -> x.values().stream()) .collect(Collectors.groupingBy(v -> v.getTitle().substring(6))) .entrySet().stream() .map(e -> new Merge().new Container(e.getValue().stream().mapToInt(x -> x.getVal()).sum(), e.getValue().get(0).getTitle())) .collect(Collectors.toMap(e -> ((Container) e).getTitle().substring(6), e -> e)); return map; } 创建您需要的地图。

如果您有任何疑问,请不要犹豫。

{aaa=24 : title_aaa, ccc=7 : title_ccc, bbb=20 : title_bbb}

这是输出

if

答案 1 :(得分:0)

使用Map.merge

private Map<String,Container> mergeContainers(Map<String,Container> a, Map<String,Container> b) {
  Map<String,Container> result = new HashMap<String,Container>(a);

  for (Entry<String,Container> entry : b.entrySet()) {
    result.merge(entry.getKey(), entry.getValue(), (aContainer,bContainer) -> MERGE_BOTH_CONTAINERS_HERE); 
  } 
  return result;
}

private Map<String,Container> mergeContainers(Iterable<Map<String,Container>> maps) {
  return mergeContainers(maps, new HashMap<String,Container>());
}

private Map<String,Container> mergeContainers(Iterable<Map<String,Container>> maps, Map<String,Container> merged) {
  return maps.hasNext() 
         ? mergeContainers(maps, mergeContainers(merged, maps.next()))
         : merged;
  }
}

现在,您可以在代码中将地图合并到:

mergeContainers(Arrays.asList(map1, map2, map3));