Java中的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流分组内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
相关文章
Java 8 对 ArrayList 元素进行排序的操作方法
Java8提供了多种方式对ArrayList元素进行排序,包括使用Collections.sort()方法、Collections.reverseOrder()实现降序排序、使用Lambda表达式进行自定义排序、使用StreamAPI对ArrayList进行排序及按对象属性排序,本文通过示例代码介绍的非常详细,感兴趣的朋友一起看看吧2024-11-11
Spring Boot中的WebSocketMessageBrokerConfigurer接口使用
在SpringBoot中,我们可以使用 WebSocketMessageBrokerConfigurer接口来配置WebSocket消息代理,以实现实时通信,具有一定的参考价值,感兴趣的可以了解一下2023-11-11
Mybatis-plus新版本分页失效PaginationInterceptor过时的问题
这篇文章主要介绍了Mybatis-plus新版本分页失效,PaginationInterceptor过时问题,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下2020-11-11
面试与实战必备:掌握Java并发编程关键知识点(线程池/CAS/性能优化)
本文从工程视角系统梳理Java并发编程的关键知识点,主要内容包括:并发问题的本质、Java内存模型、volatile和synchronized、Lock与AQS、线程池、Future与CompletableFuture、CAS与原子类、并发容器、死锁与线上排查、并发性能优化思路等一些常用代码片段2026-05-05


最新评论