文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

Java Stream流实现多字段分组groupingBy操作

2023-10-28 05:50

关注

近期的项目里,遇到一个需求:对于含有多个元素的List,按照其中的某几个属性进行分组,比如Report::getPersonID、Report::getSchoolYear、Report::getDataType等字段。下面就让我们讨论一下如何比较优雅的按多字段进行分组groupingBy。

  1. 利用单个字段进行分组
    如上面的Report类,如果对于其中的某一个字段进行分组(如PersonID),则比较简单,我们可以利用Stream.collect()和Collectors.groupingBy结合,即可进行分组groupingBy,代码如下:
public class TestGroupingBy {    public static void main(String[] args) {        List<Report> reportList = Arrays.asList(                new Person().setPersonID(1).setSchoolYear(2022).setDataType("本科")                //这里添加其他的对象,可以多添加一些        );        Map<String, List<Report>> groupingMap = reportList.stream().collect(Collectors.groupingBy(Person::getPersonID));}

其中的groupingMap ,类型为Map,第一个泛型为String即分组字段(本例中为personID字段)的类型,第二个泛型为List及分组结果的类型。
2. 利用多个字段进行分组
上面的例子是按单个字段分组,如果需要按照多个字段,如personID、schoolYear、dataType三个字段进行分组,同样也可以可以利用Stream.collect()和Collectors.groupingBy结合的方式进行分组,不过该方式中调用Collectors.groupingBy时需要多次嵌套调用,测试代码如下:

public class TestGroupingBy {    public static void main(String[] args) {        List<Report> reportList = Arrays.asList(                new Person().setPersonID(1).setSchoolYear(2022).setDataType("本科")                //这里添加其他的对象,可以多添加一些        );        // 多字段嵌套分组        Map<String, Map<Integer, Map<String, List<Report>>>> groupingMap = personList.stream().collect(                Collectors.groupingBy(Report::getPersonID,                         Collectors.groupingBy(Report::getSchoolYear,     Collectors.groupingBy(Report::getDataType)                        )                )        );    }}

其中groupingMap类型为Map>>,是一个嵌套了三层的Map,对应的泛型String/Integer/String分别为对应分组字段的类型,最后一层Map的value类型为List为实际分组后的数据集合类型。为方便查看数据,特意按Json格式贴出数据如下:

{  "1": {    "2022": {      "本科": [        {          "id": 1,          "schoolYear": 20,          "dataType": "本科"        }      ]      }      }}
  1. 利用Collectors.groupingBy与Function结合对多字段分组进行优化
public class TestGroupingBy {    public static void main(String[] args) {        List<Report> reportList = Arrays.asList(                new Person().setPersonID(1).setSchoolYear(2022).setDataType("本科")        );        // 定义一个函数Function,该函数将元素对象映射到一个键的集合里        Function<Report, List<Object>> compositeKey = report->                Arrays.asList(report.getPersonID(), report.getSchoolYear(), report.getDataType());        // 分组        Map<List<Object>, List<Report>> groupingMap =                reportList.stream().collect(Collectors.groupingBy(compositeKey, Collectors.toList()));    }}

groupingMap数据仅仅只有一层,但是其键值Key却是一个List,里面包含了分组字段的值,数据按Json格式贴出如下:

{  "[1, 2022, 本科]": [    {          "id": 1,          "schoolYear": 20,          "dataType": "本科"    }  ]}

由于Map只有一层,用该方式分组的结果,对于我们业务也是比较友好,代码里对数据处理起来也是比较方便的。可以看到,从代码书写角度以及分组处理后得到的结果,该方法都是最优雅的。

来源地址:https://blog.csdn.net/weixin_51517879/article/details/132100605

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯