我试图做一些看似直截了当的事,但到目前为止没有运气。我有一个 Map 列表,它们来自一堆CompletableFutures并行,然后必须加入结果。由于映射中的键是唯一的,因此需要合并值并生成与SomeType的组合列表关联的唯一键的新映射。例如:
地图1: key1:Sometype1 key2:Sometype2
地图2 key1:Sometype3 key2:Sometype4
期望的最终结果: MAP3: key1:Sometype,Sometype3 key2:Sometype2,Sometype4
我尝试使用groupBy和其他方法,但似乎大多数人都假设使用List而不是Map来开始,所以我无法找到一种直接的方法来实现它。
到目前为止,我有类似的内容:
Map<String, List<Sometype>> volPercent = waitGroup.stream()
.map(CompletableFuture::join)
.flatMap((e) -> e.entrySet().stream())
.collect(Collectors.groupingBy());
我不确定的部分是否需要分组。我尝试了Map.Entry :: getKey,但它没有编译:
Error:(69, 25) java: incompatible types: inference variable T has incompatible bounds
equality constraints: com.Sometype
lower bounds: java.util.Map.Entry<java.lang.String,com.Sometype>
答案 0 :(得分:6)
我假设您从一组地图开始:
Stream<Map<String, Sometype>> input = ... ;
你在平面图和收集方面做得很好。但是,你试过的代码,
input.flatMap(map -> map.entrySet().stream())
.collect(Collectors.groupingBy(Map.Entry::getKey));
为您提供一个地图,其键为String
,其值为地图条目的列表,特别是List<Map.Entry<String,Sometype>>
,而不是您想要的List<Sometype>
。你要做的是使用&#34;下游&#34;收藏家的功能在您按键分组后。您希望获取每个Map.Entry
并将其提取(映射)到其值Sometype
。这是通过mapping
收集器完成的。
现在,每个密钥可能有多个Sometype
个实例,因此您需要将它们收集到一个列表中。这是使用另一个下游收集器完成的,它将它们收集到一个列表中。这是使用熟悉的toList()
收集器完成的。
最终代码如下:
Map<String, List<Sometype>> result =
input.flatMap(map -> map.entrySet().stream())
.collect(groupingBy(Map.Entry::getKey,
mapping(Map.Entry::getValue,
toList())));
答案 1 :(得分:2)
问题在于你最初的尝试(据我所知)
Collectors.groupingBy(Map.Entry::getKey)
收集到Map<K, List<Map.Entry<K, V>>>
。
在flatMap
之后,您有一个Stream<Map.Entry<K, V>>
,其元素groupingBy
映射到K
。
但您需要Map<K, List<V>>
,因此您需要使用groupingBy
that takes a downstream collector,而不仅仅是分类器,因此您还可以将Map.Entry<K, V>
映射到V
。
像
这样的东西Collectors.groupingBy(
Map.Entry::getKey,
Collectors.mapping(
Map.Entry::getValue,
Collectors.toList()
)
)