我有一个Stream< Map< K, V > >
,我正在尝试将这些地图合并在一起,但保留列表中的重复值,因此最终类型为Map< K, List<V> >
。有没有办法做到这一点?我知道toMap
收集器有一个二进制函数来基本上选择返回哪个值,但它能跟踪转换后的列表吗?
即
如果a
是Stream< Map< String, Int > >
a.flatMap(map -> map.entrySet().stream()).collect(
Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (val1, val2) -> ??
);
答案 0 :(得分:8)
使用groupingBy:请参阅javadoc,但在您的情况下应该是这样的:
a.flatMap(map -> map.entrySet().stream())
.collect(
Collectors.groupingBy(
Map.Entry::getKey,
HashMap::new,
Collectors.mapping(Map.Entry::getValue, toList())
)
);
或者:
a.map(Map::entrySet).flatMap(Set::stream)
.collect(Collectors.groupingBy(
Map.Entry::getKey,
Collectors.mapping(Map.Entry::getValue, toList())
)
);
答案 1 :(得分:0)
这比groupingBy解决方案有点晦涩,但我只是想指出,通过提供合并功能也可以使用toMap(正如你最初设定的那样):
a.flatMap(map -> map.entrySet().stream()).collect(
Collectors.toMap(Map.Entry::getKey,
entry -> {
List<Integer> list = new ArrayList<>();
list.add(entry.getValue());
return list;
},
(list1, list2) -> {
list1.addAll(list2);
return list1;
}));