简体   繁体   English

Java 8流聚合了一个映射

[英]Java 8 stream aggregate a map

Im trying to do something seemingly straighforward but with no luck so far. 我试图做一些看似直截了当的事情但到目前为止没有运气。 I have a list of Map , they come from a bunch of CompletableFutures in parallel, the result then has to be joined. 我有一个Map列表,它们来自一堆并行的CompletableFutures,结果必须加入。 Since the key in the map is unique, In need to merge the values and produce a new map of unique keys associated with the combined list of SomeType. 由于映射中的键是唯一的,因此需要合并值并生成与SomeType的组合列表关联的唯一键的新映射。 For example: 例如:

Map1: key1 : Sometype1 key2 : Sometype2 Map1:key1:Sometype1 key2:Sometype2

Map2 key1 : Sometype3 key2 : Sometype4 Map2 key1:Sometype3 key2:Sometype4

Desired final result: Map3: key1 : Sometype, Sometype3 key2 : Sometype2, Sometype4 期望的最终结果:Map3:key1:Sometype,Sometype3 key2:Sometype2,Sometype4

I tried using groupBy and other methods, but it seems most of them assume working with a List and not a Map to begin with so I wasn't able to find a straightforward way to do it. 我尝试使用groupBy和其他方法,但似乎大多数人假设使用List而不是Map开头,所以我无法找到一种直接的方法来做到这一点。

So far I have something like: 到目前为止我有类似的东西:

 Map<String, List<Sometype>> volPercent = waitGroup.stream()
            .map(CompletableFuture::join)
            .flatMap((e) -> e.entrySet().stream())
            .collect(Collectors.groupingBy());

The part I'm not sure is what needs to go in the grouping by part. 我不确定的部分是什么需要分组。 I tried Map.Entry::getKey, but it doesn't compile: 我尝试了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>

I'll assume that you're starting with a stream of maps: 我假设你是从一组地图开始的:

Stream<Map<String, Sometype>> input = ... ;

You got pretty far with the flatmapping and collecting. 你在平面图和收集方面走得很远。 However, the code you tried, 但是,你试过的代码,

    input.flatMap(map -> map.entrySet().stream())
         .collect(Collectors.groupingBy(Map.Entry::getKey));

gives you a map whose keys are String and whose values are a list of map entries , specifically List<Map.Entry<String,Sometype>> , not a List<Sometype> as you wanted. 为您提供一个映射,其键为String ,其值为映射条目 List<Map.Entry<String,Sometype>> ,特别是List<Map.Entry<String,Sometype>> ,而不是List<Sometype> What you have to do is use the "downstream" feature of collectors after you've grouped them by key. 您需要做的是在按键分组后使用收集器的“下游”功能。 You want to take each Map.Entry and extract (map) it to its value, which is Sometype . 您想要获取每个Map.Entry并将其提取(映射)到其值,即Sometype This is done with a mapping collector. 这是通过mapping收集器完成的。

Now you potentially have several instances of Sometype for each key, so you need to collect them into a list. 现在,您可能为每个键设置了几个Sometype实例,因此您需要将它们收集到列表中。 This is done using another downstream collector, which collects them into a list. 这是使用另一个下游收集器完成的,它将它们收集到一个列表中。 This is done using the familiar toList() collector. 这是使用熟悉的toList()收集器完成的。

The final code looks like this: 最终代码如下所示:

Map<String, List<Sometype>> result =
    input.flatMap(map -> map.entrySet().stream())
         .collect(groupingBy(Map.Entry::getKey,
                             mapping(Map.Entry::getValue,
                                     toList())));

The problem is that your initial attempt (as I understand it) 问题是你最初的尝试(据我所知)

Collectors.groupingBy(Map.Entry::getKey)

collects to a Map<K, List<Map.Entry<K, V>>> . 收集到Map<K, List<Map.Entry<K, V>>>

After the flatMap , you have a Stream<Map.Entry<K, V>> whose elements groupingBy maps to K . flatMap ,你有一个Stream<Map.Entry<K, V>>其元素groupingBy映射到K

But you want a Map<K, List<V>> so you need to use the groupingBy that takes a downstream collector , not just a classifier, so you can also map Map.Entry<K, V> to V . 但是你想要一个Map<K, List<V>>所以你需要使用带有下游收集器groupingBy ,而不仅仅是一个分类器,所以你也可以将Map.Entry<K, V>映射到V

Something like 就像是

Collectors.groupingBy(
    Map.Entry::getKey,
    Collectors.mapping(
        Map.Entry::getValue,
        Collectors.toList()
    )
)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM