这是关于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
}]
有没有更优雅的方法来实现这一目标?
答案 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());