欢迎来到徐庆高(Tea)的个人博客网站
磨难很爱我,一度将我连根拔起。从惊慌失措到心力交瘁,我孤身一人,但并不孤独无依。依赖那些依赖我的人,信任那些信任我的人,帮助那些给予我帮助的人。如果我愿意,可以分裂成无数面镜子,让他们看见我,就像看见自己。察言观色和模仿学习是我的领域。像每个深受创伤的人那样,最终,我学会了随遇而安。
当前位置: 日志文章 > 详细内容

Java中的stream流分组示例详解

2025年08月19日 Java
什么是stream流java 8引入的stream api是处理集合数据的一种全新方式,它代表了对数据元素序列进行函数式操作的抽象。stream不是数据结构,而是一种高级的数据处理工具,允许你以声明式

什么是stream流

java 8引入的stream api是处理集合数据的一种全新方式,它代表了对数据元素序列进行函数式操作的抽象。stream不是数据结构,而是一种高级的数据处理工具,允许你以声明式的方式处理数据集合,类似于sql语句操作数据库。

stream的核心特点:

  • 声明式编程:只需说明"做什么"而非"如何做",代码更简洁易读
  • 函数式风格:与lambda表达式完美结合,操作更灵活
  • 管道操作:多个操作可以连接起来形成数据处理流水线
  • 内部迭代:不同于集合的外部迭代(使用for-each),stream在内部处理迭代过程
  • 延迟执行:中间操作不会立即执行,只有遇到终结操作才会触发计算
  • 不可复用:一个stream只能被消费一次

1、根据某个字段分组

 // 按 department 字段分组
        map<string, list<user>> groupedbydept = users.stream()
            .collect(collectors.groupingby(user::getdepartment));

2、按多个字段分组(组合分组)

1、方法一:使用 string 拼接作为分组 key(简单但不够灵活)

map<string, list<user>> grouped = users.stream()
    .collect(collectors.groupingby(
        user -> user.getdepartment() + "-" + user.getjobtitle()
    ));

2、使用 map.entry(java 8+ 就支持):

map<map.entry<string, string>, list<user>> grouped = users.stream()
    .collect(collectors.groupingby(
        user -> map.entry(user.getdepartment(), user.getjobtitle())
    ));

        这样 key 是一个 map.entry<部门, 职位>,可以唯一确定一个组合

3、使用 record(java 16+):

// 定义一个记录类作为分组 key
record deptjobkey(string department, string jobtitle) {}
map<deptjobkey, list<user>> grouped = users.stream()
    .collect(collectors.groupingby(
        user -> new deptjobkey(user.getdepartment(), user.getjobtitle())
    ));

3、分组后获取其他统计信息

1、分组后统计每组的数量

map<string, long> countbydept = users.stream()
    .collect(collectors.groupingby(
        user::getdepartment,
        collectors.counting()  // 统计每个部门的用户数
    ));

2、分组后获取每组中的某个属性集合,比如所有部门下的用户名

map<string, list<string>> namesbydept = users.stream()
    .collect(collectors.groupingby(
        user::getdepartment,
        collectors.mapping(user::getname, collectors.tolist()) // 只提取 name 字段
    ));

3、分组后求每组的某个属性的最大值 / 最小值 / 平均值

map<string, optional<integer>> maxagebydept = users.stream()
    .collect(collectors.groupingby(
        user::getdepartment,
        collectors.mapping(user::getage, collectors.maxby(comparator.naturalorder()))
    ));
// 或者更直观地使用 collectors.maxby / averagingint 等
//或者使用 collectors.summarizingint 做综合统计
map<string, intsummarystatistics> agestatsbydept = users.stream()
    .collect(collectors.groupingby(
        user::getdepartment,
        collectors.summarizingint(user::getage)  // 统计年龄:count, sum, min, max, avg
    ));

4、自定义分组key

map<string, list<user>> collect = javalist.stream().collect(collectors.groupingby(user -> {
            string id = user.getid();
            return (stringutils.isempty(id)) ? "empty" : "notempty"; // 如果为 null,返回empty,不为空notempty
        }));

到此这篇关于java的stream流分组的文章就介绍到这了,更多相关java stream流分组内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!