写在前面的
项目中遇到了需要对list进行分组的场景,根据List<entity>中entity的某字段或者多个字段进行分组,形成Map<String,List<entity>>,然后根据map进行相关的业务操作。
之前考虑自己遍历list进行处理,总感觉还有更便捷的方法,分享下。。
正文
java8 新特性Stream API
Stream 是 Java8 中处理集合的关键抽象概念,它可以指定你希望对集合进行的操作,可以执行比较复杂的查找、过滤和映射数据等操作。使用Stream API 对集合数据进行操作,就类似于使用 SQL 执行的数据库查询。也可以使用 Stream API 来并行执行操作。简而言之,Stream API 提供了一种高效且易于使用的处理数据的方式。
下边实现的list分组代码就使用了Stream Api。
根据一个字段进行分组
import cn.hutool.json.JSONUtil;
import com.test.collection.entity.Score;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
* 对list进行分组
*
* @ClassName: ListGroupBy
* @Author: myx
* @Date: 2020/4/5 20:22
**/
public class ListGroupBy {
public static void main(String[] args) {
List<Score> scoreList = new ArrayList<>();
scoreList.add(new Score().setStudentId("001").setScoreYear("2018").setScore(100.0));
scoreList.add(new Score().setStudentId("001").setScoreYear("2019").setScore(59.5));
scoreList.add(new Score().setStudentId("001").setScoreYear("2019").setScore(99.0));
scoreList.add(new Score().setStudentId("002").setScoreYear("2018").setScore(99.6));
//根据scoreYear字段进行分组
Map<String, List<Score>> map = scoreList.stream().collect(
Collectors.groupingBy(
score -> score.getScoreYear()
));
System.out.println(JSONUtil.toJsonPrettyStr(map));
}
}
输出结果如下:
{
"2019": [
{
"studentId": "001",
"score": 59.5,
"scoreYear": "2019"
},
{
"studentId": "001",
"score": 99,
"scoreYear": "2019"
}
],
"2018": [
{
"studentId": "001",
"score": 100,
"scoreYear": "2018"
},
{
"studentId": "002",
"score": 99.6,
"scoreYear": "2018"
}
]
}
根据多个字段进行分组
将上述代码中
//根据scoreYear字段进行分组
Map<String, List<Score>> map = scoreList.stream().collect(
Collectors.groupingBy(
score -> score.getScoreYear()
));
修改成:
//根据scoreYear和studentId字段进行分组
Map<String, List<Score>> map = scoreList.stream().collect(
Collectors.groupingBy(
score -> score.getScoreYear()+'-'+score.getStudentId()
));
输出结果如下:
{
"2019-001": [
{
"studentId": "001",
"score": 59.5,
"scoreYear": "2019"
},
{
"studentId": "001",
"score": 99,
"scoreYear": "2019"
}
],
"2018-001": [
{
"studentId": "001",
"score": 100,
"scoreYear": "2018"
}
],
"2018-002": [
{
"studentId": "002",
"score": 99.6,
"scoreYear": "2018"
}
]
}
总结
- 本文提到的list分组方式适用于Java 8版本,低版本的不支持
- 对于list多字段的分组操作,groupingBy内传入的是多个字段拼接起来的一个复合字段,分组后形成map的key,就是拼接后的复合字段
结尾:
本文记录的只是Stream Api对list的分组操作,若对这方面比较感兴趣,可以自己再找资料专门学习一下。