java 使用stream流进行分组
时间: 2025-07-04 14:05:48 浏览: 0
在Java 8中,`Stream API` 提供了强大的数据处理能力,尤其是在集合操作方面。其中,`Collectors.groupingBy()` 是一个非常常用的工具,用于根据某些属性对集合中的元素进行分组,并将结果存储为 `Map` 结构。
### 基本用法
最简单的分组是基于单个字段进行分组。例如,假设有一个 `List<Student>`,需要按照学生的年级进行分组:
```java
Map<String, List<Student>> groupedByGrade = students.stream()
.collect(Collectors.groupingBy(Student::getGrade));
```
上述代码中,`Student::getGrade` 是分组的依据,最终的结果是一个 `Map`,键是年级,值是对应年级的所有学生列表[^1]。
### 多级分组
对于更复杂的场景,可以使用嵌套的 `groupingBy` 方法实现多层分组。例如,先按年级分组,再按性别分组:
```java
Map<String, Map<String, List<Student>>> groupedByGradeAndGender = students.stream()
.collect(Collectors.groupingBy(Student::getGrade,
Collectors.groupingBy(Student::getGender)));
```
这种结构返回的是一个嵌套的 `Map`,外层键是年级,内层键是性别,值是符合该年级和性别的学生列表[^2]。
### 分组后聚合操作
除了将数据分组,还可以结合其他收集器(如 `averagingDouble`、`summingDouble`、`counting`)来执行聚合操作。例如,计算每个年级学生的平均年龄:
```java
Map<String, Double> averageAgeByGrade = students.stream()
.collect(Collectors.groupingBy(Student::getGrade,
Collectors.averagingDouble(Student::getAge)));
```
类似地,可以统计每个年级的学生人数:
```java
Map<String, Long> countByGrade = students.stream()
.collect(Collectors.groupingBy(Student::getGrade,
Collectors.counting()));
```
### 多字段分组
当需要基于多个字段进行唯一性校验或分组时,可以构造一个复合键。例如,确保某个数据结构中没有重复的 `(rCode, pCode)` 组合:
```java
Map<String, List<XXX>> groupedByKey = list.stream()
.collect(Collectors.groupingBy(item -> item.getRCode() + ";" + item.getPCode()));
```
然后可以遍历这个 `Map` 并检查每个键对应的列表长度是否大于 1,以判断是否存在重复数据:
```java
for (String key : groupedByKey.keySet()) {
if (groupedByKey.get(key).size() > 1) {
throw new IllegalArgumentException("存在重复数据: " + key);
}
}
```
这种方式非常适合用于业务逻辑中的去重校验或唯一性约束验证[^3]。
---
阅读全文
相关推荐


















