You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 01:40:02