实体类:
@Data
public static class Person{
// 姓名
private String name;
// 性别
private String gender;
// 年龄
private Integer age;
// 城市
private String city;
// 工资
private Double salary;
}
测试各种分组:
public static void main(String[] args) {
List<Person> personList = new ArrayList<>();
// todo 添加元素
// 1.按照城市分组
Map<String, List<Person>> collect = personList
.stream()
.collect(Collectors.groupingBy(Person::getCity));
// 2.按照城市和性别分组
Map<String, List<Person>> collect1 = personList
.stream()
.collect(Collectors.groupingBy(p ->
// 这里是Map的key: city_gender
p.city + "_" + p.gender
));
// 3.按照条件分组 A组:20岁以下 B组:20到60岁 C组:60岁以上的
Map<String, List<Person>> collect2 = personList.stream()
.collect(Collectors.groupingBy(p -> {
if(p.getAge() < 20){
// map的key是A
return "A";
}else if(p.getAge()>=20 && p.getAge()<=60){
// map的key是B
return "B";
}else {
// map的key是C
return "C";
}
}));
//4.多级分组 先按照城市分组 在按照年龄分组
//要实现多级分组,可以使用一个由双参数版本的Collectors.groupingBy工厂方法创建的收集器,
// 它除了普通的分类函数之外,还可以接受collector类型的第二个参数。
// 那么要进行二级分组的话,我们可以把一个内层groupingBy传递给外层groupingBy,并定义一个为流中项目分类的二级标准。
Map<String, Map<String, List<Person>>> collect3 = personList
.stream()
.collect(Collectors.groupingBy(
Person::getCity, // 一级分组:城市
Collectors.groupingBy(p -> { // 二级分组:年龄
if (p.getAge() < 20) {
// map的key是A
return "A";
} else if (p.getAge() >= 20 && p.getAge() <= 60) {
// map的key是B
return "B";
} else {
// map的key是C
return "C";
}
})));
// 5.分组求每组数量 每个城市有几个人
Map<String, Long> collect4 = personList
.stream()
.collect(Collectors.groupingBy(
Person::getCity,
Collectors.counting()
)
);
// 6.每个城市的人的工资总和
Map<String, Double> collect5 = personList
.stream()
.collect(Collectors.groupingBy(Person::getCity, Collectors.summingDouble(Person::getSalary)));
// 7.找到每个城市的员工姓名 联合其他的收集器使用
Map<String, List<String>> collect6 = personList
.stream()
.collect(Collectors.groupingBy(Person::getCity, Collectors.mapping(Person::getName, Collectors.toList())));
}