Java 8 Lambda(一步分组和缩减)

man*_*ni0 6 java lambda grouping java-8 java-stream

假设我有一个Pair对象列表,

List<Pair<A,B>> listOfPairs = //some list of pairs ; 
Run Code Online (Sandbox Code Playgroud)

我想将此列表分组为Map<A,Set<B>>.

目前,我可以分两步完成.第一步按A组,并返回 Map<A,Set<Pair<A,B>>如下:

   Map<A,Set<Pair<A,B>> intermediateStep =   listOfPairs.stream().collect(Collectors.groupingBy((Pair::getLeft), Collectors.toSet()));
Run Code Online (Sandbox Code Playgroud)

然后我流式传输上面地图的入口集并将它们收集到所需的最终结果中,主要是通过将每个Pair对象映射到其B值,并将它们收集到一个集合中:

 Map<A, Set<B>> finalResult= intermediateStep.entrySet().stream().collect(Collectors.toMap(e -> e.getKey(), e -> e.getValue().stream().map(Pair::getRight).collect(Collectors.toSet())));
Run Code Online (Sandbox Code Playgroud)

有没有更好的方法来实现预期的结果,也许是一步到位?换句话说,上述中间步骤按A分组,但分组的右侧返回整个Pair对象.我想按A分组,并在一步中将A指向其相关B的集合.

(我知道,仅仅因为我可以一步到位,并不意味着我应该这样做,因为可读性可能会受到影响,但我很好奇.)

谢谢!

Ous*_* D. 13

您可以通过将mapping收集器传递到收集器来简化代码,groupingBy如下所示:

Map<A, Set<B>> collect = 
       listOfPairs.stream()
                  .collect(Collectors.groupingBy(Pair::getLeft, 
                                Collectors.mapping(Pair::getRight,
                                       Collectors.toSet())));
Run Code Online (Sandbox Code Playgroud)