如何用Java 8的reduce方法计算A级员工平均薪资(不使用内置方法)
用Stream.reduce实现A级员工平均薪资计算
要手动用reduce实现平均薪资计算,核心是同时维护薪资总和和员工计数两个状态——因为平均值需要这两个数据推导出来。下面提供两种实现方式,分别基于数组和自定义类,逻辑和你写的经典循环完全对应,只是用函数式的reduce替代了手动遍历。
方式一:用数组作为状态容器
数组的两个元素分别存总和(索引0)和计数(索引1),逻辑直观,适合快速实现:
static void testReduceWithArray() { Optional<double[]> stats = getEmployees().stream() .filter(emp -> emp.getGrade().equalsIgnoreCase("A")) // 初始状态:总和0,计数0 .reduce(new double[]{0.0, 0}, // 累加器:处理单个A级员工,更新总和和计数 (acc, emp) -> { acc[0] += emp.getSalary(); acc[1] += 1; return acc; }, // 合并器:并行流时合并不同线程的统计结果 (acc1, acc2) -> { acc1[0] += acc2[0]; acc1[1] += acc2[1]; return acc1; }); // 处理结果,避免无A级员工时除以0 if (stats.isPresent()) { double[] result = stats.get(); if (result[1] > 0) { double average = result[0] / result[1]; System.out.println("REDUCE(数组) approach: average salary of grade A employees : " + average); } else { System.out.println("No grade A employees found"); } } }
方式二:用自定义类封装状态
如果追求可读性和可维护性,可以自定义一个类来封装统计状态,代码更清晰:
// 自定义统计类,封装总和与计数 static class SalaryStats { private double totalSalary; private int count; public SalaryStats(double totalSalary, int count) { this.totalSalary = totalSalary; this.count = count; } // 累加单个员工的薪资 public SalaryStats accumulate(Employee emp) { return new SalaryStats(this.totalSalary + emp.getSalary(), this.count + 1); } // 合并两个统计结果(并行流时用) public SalaryStats combine(SalaryStats other) { return new SalaryStats(this.totalSalary + other.totalSalary, this.count + other.count); } // 计算平均值,处理计数为0的情况 public double getAverage() { if (count == 0) { throw new IllegalStateException("No grade A employees to calculate average"); } return totalSalary / count; } } // 使用自定义类的reduce实现 static void testReduceWithCustomClass() { Optional<SalaryStats> stats = getEmployees().stream() .filter(emp -> emp.getGrade().equalsIgnoreCase("A")) .reduce(new SalaryStats(0.0, 0), SalaryStats::accumulate, SalaryStats::combine); stats.ifPresent(s -> System.out.println("REDUCE(自定义类) approach: average salary of grade A employees : " + s.getAverage())); }
核心逻辑说明
reduce的本质就是把你经典循环里的sum和count累加逻辑,拆成初始状态、单个元素累加规则、并行结果合并规则三个部分- 内置的
average()方法底层也是类似的reduce逻辑,只是Java帮你封装好了状态维护和计算细节 - 一定要处理无A级员工的情况,避免出现除以0的算术异常
内容的提问来源于stack exchange,提问作者let_there_be_peace
相关产品推荐
相关产品推荐

