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

如何为Java Stream.reduce实现自定义累加器与组合器求最大差值?

使用Stream.reduce()计算双精度列表的最大差值

要通过Stream.reduce()实现一次遍历即可计算列表的最大差值(最大值减最小值),核心思路是在归约过程中同时跟踪当前遍历到的最小值和最大值,最终用两者的差得到结果。

方案1:使用double数组作为累加器(轻量实现)

用数组的第一个元素存储当前最小值,第二个元素存储当前最大值,代码如下:

List<Double> list = List.of(1.1, 0.3, 7.8, 1.0, 9.1, 2.3);

// 归约操作:同时跟踪min和max
double[] minMax = list.stream()
    .reduce(
        // 初始值:设置为极端值,确保第一个元素能正确更新min和max
        new double[]{Double.MAX_VALUE, Double.MIN_VALUE},
        // 累加器:处理单个元素,更新当前min和max
        (current, num) -> new double[]{
            Math.min(current[0], num),
            Math.max(current[1], num)
        },
        // 组合器:并行流场景下,合并两个分片的min和max结果
        (left, right) -> new double[]{
            Math.min(left[0], right[0]),
            Math.max(left[1], right[1])
        }
    );

double maxDiff = minMax[1] - minMax[0];
System.out.println(maxDiff); // 输出8.8

方案2:自定义MinMax类(可读性更强)

如果觉得数组不够直观,可以自定义一个简单的容器类来封装min和max:

// 静态内部类,用于保存当前的最小/最大值
static class MinMax {
    private final double min;
    private final double max;

    MinMax(double min, double max) {
        this.min = min;
        this.max = max;
    }
}

public static void main(String[] args) {
    List<Double> list = List.of(1.1, 0.3, 7.8, 1.0, 9.1, 2.3);

    MinMax result = list.stream()
        .reduce(
            new MinMax(Double.MAX_VALUE, Double.MIN_VALUE),
            (current, num) -> new MinMax(Math.min(current.min, num), Math.max(current.max, num)),
            (left, right) -> new MinMax(Math.min(left.min, right.min), Math.max(left.max, right.max))
        );

    double maxDiff = result.max - result.min;
    System.out.println(maxDiff); // 输出8.8
}

空列表处理(与原方案行为对齐)

原方案中如果列表为空,调用get()会抛出NoSuchElementException。我们可以调整reduce的写法,返回Optional来匹配这个行为:

List<Double> emptyList = List.of();

Optional<double[]> optionalResult = emptyList.stream()
    .reduce(
        (current, num) -> new double[]{Math.min(current[0], num), Math.max(current[1], num)},
        (left, right) -> new double[]{Math.min(left[0], right[0]), Math.max(left[1], right[1])}
    );

// 空列表时抛出异常,和原方案一致
double maxDiff = optionalResult.map(arr -> arr[1] - arr[0])
    .orElseThrow(() -> new NoSuchElementException("No value present"));

优势对比

和你原来两次调用max()/min()的方案相比,用reduce的方式只需要一次流遍历,在数据量较大时效率更高;同时组合器的存在让这个实现天然支持并行流,不需要额外修改代码。

内容的提问来源于stack exchange,提问作者Andy

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 20:05:17