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

Java8 Stream计算四数最小最大和结果异常问题排查

问题描述

给定5个正整数,计算选取恰好4个整数求和可得到的最小值、最大值,最终将两个long类型的计算结果以空格分隔为单行输出。

异常表现
  • 小数值测试用例运行正常:输入[1, 2, 3, 4, 5]时,输出最小值10、最大值14,结果符合预期
  • 大数值测试用例运行失败:输入[256741038, 623958417, 467905213, 714532089, 938071625]时,代码输出最小值2063136757、最大值-1550499952,预期正确结果为最小值2063136757、最大值2744467344
  • 初步定位:问题大概率出现在long max的赋值语句处,尤其是.sorted(Collections.reverseOrder())逻辑,这是最小和、最大和计算语句之间唯一的实质差异
原实现代码
class Result {
    
    /*
     * Complete the 'miniMaxSum' function below.
     *
     * The function accepts. INTEGER_ARRAY arr as parameter.
     */
    
    public static void miniMaxSum(List<Integer> arr) {
        long max = arr.stream().sorted(Collections.reverseOrder())
                .limit(4)
                .reduce(0, (subtotal, element) -> subtotal + element);
        long min = arr.stream().sorted().limit(4).reduce(0,
                (subtotal, element) -> subtotal + element);
        System.out.println(min + " " + max);
    }
}

public class Solution {
    public static void main(String[] args) throws IOException {
        BufferedReader bufferedReader =
                new BufferedReader(new InputStreamReader(System.in));
        
        List<Integer> arr = Stream
                .of(bufferedReader.readLine().replaceAll("\\s+$", "")
                        .split(" "))
                .map(Integer::parseInt).collect(toList());
        
        Result.miniMaxSum(arr);
        
        bufferedReader.close();
    }
}
问题根因

问题和倒序排序逻辑无关,核心是reduce操作的初始值0为int类型,导致整个累加过程按int类型运算,触发整数溢出:

  1. Java中int类型的最大值为2^31-1 = 2147483647,一旦累加和超过这个值就会溢出为负数
  2. 计算最小和时,取正序排列的前4个最小数相加,和为2063136757,小于int最大值,未触发溢出,因此结果正确
  3. 计算最大和时,取倒序排列的前4个最大数相加,和为2744467344,远大于int最大值,累加过程中int溢出得到负数结果,即便最终赋值给long类型,保存的也已经是溢出后的错误值
修复方案

将reduce的初始值从int类型的0改为long类型的0L,让整个累加过程按long类型运算,从根源避免整数溢出。修复后的核心代码如下:

public static void miniMaxSum(List<Integer> arr) {
    long max = arr.stream().sorted(Collections.reverseOrder())
            .limit(4)
            .reduce(0L, (subtotal, element) -> subtotal + element);
    long min = arr.stream().sorted().limit(4).reduce(0L,
            (subtotal, element) -> subtotal + element);
    System.out.println(min + " " + max);
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 12:01:05