近期的项目里,遇到一个需求:对于含有多个元素的List,按照其中的某几个属性进行分组,比如Report::getPersonID、Report::getSchoolYear、Report::getDataType等字段。下面就让我们讨论一下如何比较优雅的按多字段进行分组groupingBy。
- 利用单个字段进行分组
如上面的Report类,如果对于其中的某一个字段进行分组(如PersonID),则比较简单,我们可以利用Stream.collect()和Collectors.groupingBy结合,即可进行分组groupingBy,代码如下:
public class TestGroupingBy { public static void main(String[] args) { List<Report> reportList = Arrays.asList( new Person().setPersonID(1).setSchoolYear(2022).setDataType("本科") //这里添加其他的对象,可以多添加一些 ); Map<String, List<Report>> groupingMap = reportList.stream().collect(Collectors.groupingBy(Person::getPersonID));}
其中的groupingMap ,类型为Map
2. 利用多个字段进行分组
上面的例子是按单个字段分组,如果需要按照多个字段,如personID、schoolYear、dataType三个字段进行分组,同样也可以可以利用Stream.collect()和Collectors.groupingBy结合的方式进行分组,不过该方式中调用Collectors.groupingBy时需要多次嵌套调用,测试代码如下:
public class TestGroupingBy { public static void main(String[] args) { List<Report> reportList = Arrays.asList( new Person().setPersonID(1).setSchoolYear(2022).setDataType("本科") //这里添加其他的对象,可以多添加一些 ); // 多字段嵌套分组 Map<String, Map<Integer, Map<String, List<Report>>>> groupingMap = personList.stream().collect( Collectors.groupingBy(Report::getPersonID, Collectors.groupingBy(Report::getSchoolYear, Collectors.groupingBy(Report::getDataType) ) ) ); }}
其中groupingMap类型为Map
{ "1": { "2022": { "本科": [ { "id": 1, "schoolYear": 20, "dataType": "本科" } ] } }}
- 利用Collectors.groupingBy与Function结合对多字段分组进行优化
public class TestGroupingBy { public static void main(String[] args) { List<Report> reportList = Arrays.asList( new Person().setPersonID(1).setSchoolYear(2022).setDataType("本科") ); // 定义一个函数Function,该函数将元素对象映射到一个键的集合里 Function<Report, List<Object>> compositeKey = report-> Arrays.asList(report.getPersonID(), report.getSchoolYear(), report.getDataType()); // 分组 Map<List<Object>, List<Report>> groupingMap = reportList.stream().collect(Collectors.groupingBy(compositeKey, Collectors.toList())); }}
groupingMap数据仅仅只有一层,但是其键值Key却是一个List,里面包含了分组字段的值,数据按Json格式贴出如下:
{ "[1, 2022, 本科]": [ { "id": 1, "schoolYear": 20, "dataType": "本科" } ]}
由于Map只有一层,用该方式分组的结果,对于我们业务也是比较友好,代码里对数据处理起来也是比较方便的。可以看到,从代码书写角度以及分组处理后得到的结果,该方法都是最优雅的。
来源地址:https://blog.csdn.net/weixin_51517879/article/details/132100605