在 Java8 中,可以使用 Stream API 的 Collectors.groupingBy
方法将流中的元素按照指定的分类函数进行分组,并生成一个 Map
对象,然后可以使用 Collectors.counting()
、Collectors.summingInt()
、Collectors.reducing()
、Collectors.collectingAndThen()
等方法对分组后的集合进行计数
、求和
、规约
、集合处理
等操作。
import lombok.Data;
import java.util.*;
import java.util.function.BinaryOperator;
import java.util.function.Function;
import java.util.stream.Collectors;
/**
* @Title MyClass
*
@Description java8 聚合/归约测试
*
* @author ACGkaka
* @date 2023/4/13 19:15
*/
public class MyClass {
public static void main(String[] args) {
List<Person> persons = Arrays.asList(
new Person("Alice", "Female", 25),
new Person("Bob", "Male", 30),
new Person("Charlie", "Male", 35),
new Person("Dave", "Male", 30),
new Person("Eve", "Female", 25)
);
// 按照性别分组,并计算每组的人数
Map<String, Long> countByGender = persons.stream()
.collect(Collectors.groupingBy(Person::getGender, Collectors.counting()));
System.out.println("countByGender = " + countByGender);
// 按照性别分组,并计算每组的年龄总和(实现方式一)(推荐)
Map<String, Integer> ageSumByGender1 = persons.stream()
.collect(Collectors.groupingBy(Person::getGender, Collectors.summingInt(Person::getAge)));
System.out.println("ageSumByGender1 = " + ageSumByGender1);
// 按照性别分组,并计算每组的年龄总和(实现方式二:归约)(不推荐)
Map<String, Integer> ageSumByGender2 = persons.stream()
.collect(Collectors.groupingBy(Person::getGender, Collectors.reducing(0, Person::getAge, Integer::sum)));
System.out.println("ageSumByGender2 = " + ageSumByGender2);
// 按照性别分组,并计算每组的最大年龄(实现方式一:集合处理)(非常不推荐)
Map<String, Person> ageMaxByGender1 = persons.stream()
.collect(Collectors.groupingBy(Person::getGender,
Collectors.collectingAndThen(Collectors.maxBy(Comparator.comparing(Person::getAge)), Optional::get)));
System.out.println("ageMaxByGender1 = " + ageMaxByGender1);
// 按照性别分组,并计算每组的最大年龄(实现方式二:转映射)(推荐)
Map<String, Person> ageMaxByGender2 = persons.stream()
.collect(Collectors.toMap(Person::getGender, Function.identity(), BinaryOperator.maxBy(Comparator.comparing(Person::getAge))));
System.out.println("ageMaxByGender2 = " + ageMaxByGender2);
}
@Data
static class Person {
private String name;
private String gender;
private int age;
public Person(String name, String gender, int age) {
this.name = name;
this.gender = gender;
this.age = age;
}
}
}
归约
:是将一个集合中的元素合并成一个结果。通常返回一个单一的值。聚合
:是将一个集合中的元素按照某种规则分组或分类,并对每个组或类别进行汇总计算。通常返回一个包含汇总结果的数据结构(如Map、List等)。整理完毕,完结撒花~
参考地址:
1.java8中 Collectors.groupingBy用法,https://blog.csdn.net/weixin_40482816/article/details/115379695