如何通过某个键的值合并多个地图?

时间:2017-02-17 08:22:38

标签: java dictionary merge

这是关于Java的,但为了便于阅读,我将用JSON编写示例。

假设我List的{​​{1}}设置如下:

Map

我想要做的是合并具有相同[{ "id": 1, "foo": 12, "bar": 34 }, { "id": 1, "baz": 56 }, { "id": 2, "foo": 78 }, { "id": 2, "bar": 90 }] 的地图。基本上,我想最终得到这样的东西:

id

我发现的所有其他问题都涉及以不相关的方式合并地图,而且大多数只关注两张地图,而不是可变数量。

这段代码看起来很有效,但有点儿冗长:

[{
    "id": 1,
    "foo": 12,
    "bar": 34,
    "baz": 56
}, {
    "id": 2,
    "foo": 78,
    "bar": 90
}]

有没有更优雅的方法来实现这一目标?

3 个答案:

答案 0 :(得分:3)

我会将结果整理到Map地图

Map<Integer, Map<String,Integer>> mapOfMaps = new HashMap<Integer, Map<String,Integer>>();

for(Map<String,Integer> map : list){
    Integer id = map.get("id");
    Map<String,Integer> existingMap = mapOfMaps.get(id);
    if(existingMap == null){
        mapOfMaps.put(id, map);
    }else{
        existingMap.putAll(map);
    }
}

正如我上面评论的那样:如果你需要对值进行求和(除id之外的地图不共享其他键,或者如果它们确实值将被替换)

答案 1 :(得分:2)

只需制作一张groupMap即新地图,其中id为关键字,元素地图为值:

    List<Map<String, Integer>> toRemove = new ArrayList<Map<String, Integer>>();
    Map<Integer, Map<String, Integer>> groupMap = new HashMap<>();

    for (Map<String, Integer> m : toRemove) {
        Integer id = m.get("id");
        Map<String, Integer> tmp = groupMap.get(id);
        if (tmp == null) {
            groupMap.put(id, m);
        } else {
            tmp.putAll(m);
        }
    }

    List<Map<String, Integer>> newList = new ArrayList<>(groupMap.values());

然后,newList就是你现在的结果。

答案 2 :(得分:1)

我的流程解决方案:

List<Map<String, Integer>> result = list.stream()
        .collect(Collectors.groupingBy(m -> m.get("id")))
        .values().stream()
        .map(m -> m.stream().<Map<String, Integer>>collect(HashMap::new, Map::putAll, Map::putAll))
        .collect(Collectors.toList());