浅谈:Java stream流式计算的优美之分组聚合
·
groupingBy()是Stream API中最强大的收集器Collector之一,提供与SQL的GROUP BY子句类似的功能。
使用stream流通过传递lambda表达式,可以让代码看上去很简洁。
此外,还可以用Java Stream和Collectors轻松完成字段的聚合。比如:相加,取平均数,或最大/最小值。更好的帮助我们分析数据。
目录
数据准备
员工类
// 员工类
public class Employee{
//部门
private String deptId;
//姓名
private String name;
//年龄
private int age;
//性别
private String sex;
//薪资
private int salary;
// 构造方法
public Employee(String deptId, String name, int age, String sex, int salary) {
this.deptId = deptId;
this.name = name;
this.age = age;
this.sex = sex;
this.salary = salary;
}
// 省略了get和set,请自行添加
}
// 实例化对象
Employee emp1 = new Employee("1201","张三",26,"男",7000);
Employee emp2 = new Employee("1202","李四",27,"男",7500);
Employee emp3 = new Employee("1203","王五",26,"女",7800);
Employee emp4 = new Employee("1201","赵六",24,"女",7000);
Employee emp5 = new Employee("1202","钱七",28,"男",5000);
Employee emp6 = new Employee("1201","老八",34,"男",8000);
员工list
// 利用stream,转为员工清单list
List<Employee> emps = Stream.of(emp1,emp2,emp3,emp4,emp5,emp6).collect(Collectors.toList());
分组
按部门进行分组
// 按照部门进行分组
Map<String, List<Employee>> collect = emps.stream().collect(Collectors.groupingBy(Employee::getDeptId));
System.out.println(collect);
分组得到ConcurrentMap
// 分组后得到一个线程安全的ConcurrentMap
ConcurrentMap<String, List<Employee>> collect = emps.stream().collect(Collectors.groupingByConcurrent(Employee::getDeptId));
System.out.println(collect);
分组得到每个部门的员工姓名
// 按照部门分组,得到每个部门的员工姓名
Map<String, List<String>> collect = emps.stream().collect(Collectors.groupingBy(Employee::getDeptId, Collectors.mapping(Employee::getName, Collectors.toList())));
System.out.println(collect);
嵌套分组
// 先按部门分组,再按性别分组
Map<String, Map<Integer, List<Employee>>> collect = emps.stream().collect(Collectors.groupingBy(Employee::getDeptId, Collectors.groupingBy(Employee::getSex)));
System.out.println(collect);
计数count
// 统计每个部门的人数,得到map集合
Map<String, Long> collect = emps.stream().collect(Collectors.groupingBy(Employee::getDeptId, Collectors.counting()));
System.out.println(collect);
计算平均值
// 计算每个部门的平均薪水
Map<String, Double> collect = emps.stream().collect(Collectors.groupingBy(Employee::getDeptId, Collectors.averagingDouble(Employee::getSalary)));
System.out.println(collect);
求和
// 计算每个部门的整体薪水
Map<String, Double> collect = emps.stream().collect(Collectors.groupingBy(Employee::getDeptId, Collectors.summingInt(Employee::getSalary)));
System.out.println(collect);
排序
// 根据薪水分组并小到大排序,TreeMap默认为按照key升序
TreeMap<Integer, List<String>> collect = emps.stream().collect(Collectors.groupingBy(Employee::getSalary, TreeMap::new, Collectors.mapping(Employee::getName, Collectors.toList())));
System.out.println(collect);
DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。
更多推荐

所有评论(0)