Stream Collectors.groupingBy的四种用法 解决分组统计(计数、求和、平均数等)、范围统计、分组合并、分组结果自定义映射等问题

前言

近期,由于业务需要,会统计一些简单的页面指标,如果每个统计都通过SQL实现的话,又略感枯燥乏味。于是选择使用Stream的分组功能。对于这些简单的统计指标来说,Stream的分组更为灵活,只需要提取出需要统计的数据,便可以对这些数据进行任意处理,而无需再次编写不同的SQL去统计不同的指标。

此文主要是总结我在此前的工作中使用到的Collectors.groupingBy的一些方法和技巧。根据平时使用的习惯,将Collectors.groupingBy的功能大致分为四种,但这种界定都是模糊的,并不是绝对,每种功能都可以穿插使用,这里只是更方便了解Collectors.groupingBy各个方法的使用规则。

四种分组功能如下:

  1. 基础分组功能
  2. 分组统计功能
  3. 分组合并功能
  4. 分组自定义映射功能

Stream的其它用法可以参考下文:





语法说明

基础语法

Collector<T, ?, Map<K, List<T>>> groupingBy(Function<? super T, ? extends K> classifier)


Collector<T, ?, Map<K, D>> groupingBy(Function<? super T, ? extends K> classifier, Collector<? super T, A, D> downstream)


Collector<T, ?, M> groupingBy(Function<? super T, ? extends K> classifier, Supplier<M> mapFactory, Collector<? super T, A, D> downstream)

  • classifier:键映射:该方法的返回值是键值对的 键
  • mapFactory:无参构造函数提供返回类型:提供一个容器初始化方法,用于创建新的 Map容器 (使用该容器存放值对)。
  • downstream:值映射:通过聚合方法将同键下的结果聚合为指定类型,该方法返回的是键值对的 值。



前置数据

List<Student> students = Stream.of(
        Student.builder().name("小张").age(16).clazz("高一1班").course("历史").score(88).build(),
        Student.builder().name("小李").age(16).clazz("高一3班").course("数学").score(12).build(),
        Student.builder().name("小王").age(17).clazz("高二1班").course("地理").score(44).build(),
        Student.builder().name("小红").age(18).clazz("高二1班").course("物理").score(67).build(),
        Student.builder().name("李华").age(15).clazz("高二2班").course("数学").score(99).build(),
        Student.builder().name("小潘").age(19).clazz("高三4班").course("英语").score(100).build(),
        Student.builder().name("小聂").age(20).clazz("高三4班").course("物理").score(32).build()
).collect(Collectors.toList());





分组的4种使用方法


1. 基础分组功能

说明:基础功能,分组并返回Map容器。将用户自定义的元素作为键,同时将键相同的元素存放在List中作为值。

Collectors.groupingBy:基础分组功能

下面的写法都是等价的

// 将不同课程的学生进行分类
Map<String, List<Student>> groupByCourse = students.stream().collect(Collectors.groupingBy(Student::getCourse));
Map<String, List<Student>> groupByCourse1 = students.stream().collect(Collectors.groupingBy(Student::getCourse, Collectors.toList()));
// 上面的方法中容器类型和值类型都是默认指定的,容器类型为:HashMap,值类型为:ArrayList
// 可以通过下面的方法自定义返回结果、值的类型
Map<
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值