分组对象java 8 [英] grouping objects java 8

查看:171
本文介绍了分组对象java 8的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下内容:

public class MyClass {
private Long stackId
private Long questionId
}

一个100的集合,其中stackid可以是不同的questionIds。它是stackId和questionId之间的一对多关系

A collection of say 100, where the stackid could be duplicate with different questionIds. Its a one to many relationship between stackId and questionId

是否有 streamy ,java 8方式转换为下面的strcuture:

Is there a streamy, java 8 way to convert to the below strcuture :

public class MyOtherClass {
private Long stackId
private Collection<Long> questionIds
}

这是25的集合,每个实例都有一个嵌套的集合4个问题。

Which would be a collection of 25, with each instance having a nested collection of 4 questionIds.

输入:

[{1,100},{1,101},{1,102},{1,103},{2,200},{2,201},{2,202},{1,203}]

输出

[{1, [100,101,102,103]},{2,[200,201,202,203]}]


推荐答案

Stream API的直接方式涉及2流管道:

The straight-forward way with the Stream API involves 2 Stream pipelines:


  • 第一个创建临时 Map< Long,List< Long>> of stackId to questionIds 。这是通过 groupingBy(分类器,下游) 收集器,我们根据 stackId 和具有相同 stackId 的值被映射到他们的 questionId (带有 映射 )并使用 toList()

  • 第二个将该地图的每个条目转换为 MyOtherClass 实例并将其收集到列表中。

  • The first one creates a temporary Map<Long, List<Long>> of stackId to questionIds. This is done with the groupingBy(classifier, downstream) collectors where we classify per the stackId and values having the same stackId are mapped to their questionId (with mapping) and collected into a list with toList().
  • The second one converts each entry of that map into a MyOtherClass instance and collects that into a list.

假设您有一个构造函数 MyOtherClass(Long stackId,Collection< Long> questionIds),示例代码woul d be:

Assuming you have a constructor MyOtherClass(Long stackId, Collection<Long> questionIds), a sample code would be:

Map<Long, List<Long>> map = 
    list.stream()
        .collect(Collectors.groupingBy(
            MyClass::getStackId,
            Collectors.mapping(MyClass::getQuestionId, Collectors.toList())
        ));

List<MyOtherClass> result = 
    map.entrySet()
       .stream()
       .map(e -> new MyOtherClass(e.getKey(), e.getValue()))
       .collect(Collectors.toList());






使用StreamEx 库,您可以在单个Stream管道中执行此操作。该库提供了 配对 第一个 收藏家。这样可以将两个收集器配对并对两个收集的结果执行修整器操作:


Using StreamEx library, you could do that in a single Stream pipeline. This library offers a pairing and first collectors. This enables to pair two collectors and perform a finisher operation on the two collected results:


  • 第一个只保留第一个 stackId 分组元素(它们都是相同的,通过构造)

  • 第二个将每个元素映射到它们的 questionId 并收集到列表中。

  • 整理器操作只返回 MyOtherClass 的新实例。

  • The first one only keeps the first stackId of the grouped elements (they will all be the same, by construction)
  • The second one mapping each element into their questionId and collecting into a list.
  • The finisher operation just returns a new instance of MyOtherClass.

示例代码:

import static java.util.stream.Collectors.collectingAndThen;
import static java.util.stream.Collectors.mapping;
import static java.util.stream.Collectors.toList;
import static one.util.streamex.MoreCollectors.first;
import static one.util.streamex.MoreCollectors.pairing;

// ...

Collection<MyOtherClass> result = 
    StreamEx.of(list)
            .groupingBy(
                MyClass::getStackId,
                pairing(
                    collectingAndThen(mapping(MyClass::getStackId, first()), Optional::get),
                    mapping(MyClass::getQuestionId, toList()),
                    MyOtherClass::new
                )
            ).values();

这篇关于分组对象java 8的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆