intsummarystatistics是collectors.summarizingint的归约结果容器,专用于流式统计整数字段;适合从对象列表提取年龄、价格等int值后一次性获取计数、总和、最值及平均值,不可手动创建或添加数据。

IntSummaryStatistics 是什么,适合在哪儿用
它不是用来实时计算的工具类,而是 Collectors.summarizingInt 的归约结果容器,专为流式统计整数字段设计。适合你已经有一组 int 值(比如从对象列表里提取年龄、价格、ID),想一口气拿到计数、总和、最大值、最小值、平均值——且不希望手写循环或多次遍历。
别把它当 Math.max() 替代品;也别试图 new 它自己塞数据,它没 public 构造器,只能靠收集器生成。
怎么正确创建并获取 max/min/average
必须走 Stream + Collector 流程,不能直接 new 或手动 add。常见错误是试图调用 new IntSummaryStatistics().accept(10),这会编译失败——accept 是 package-private 的。
- 从集合提取 int 值:用
mapToInt()转成IntStream,再 collect - 从对象列表提取字段:用
collect(Collectors.summarizingInt(obj -> obj.age)) - 空流会返回 count=0、sum=0、min=Integer.MAX_VALUE、max=Integer.MIN_VALUE、average=0.0 —— 注意 min/max 初始值不是 null,但业务上可能需要判空处理
List<Integer> numbers = Arrays.asList(3, 1, 4, 1, 5);
IntSummaryStatistics stats = numbers.stream()
.mapToInt(Integer::intValue)
.collect(Collectors.summarizingInt(i -> i));
System.out.println(stats.getMax()); // 5
System.out.println(stats.getAverage()); // 2.8
getAverage() 返回 double,但结果可能不准
getAverage() 内部用的是 long sum / (double) count,看似没问题,但整数溢出风险藏得深:如果 sum 超过 Long.MAX_VALUE(比如一亿个一千万),就会溢出变负,平均值直接错乱。
立即学习“Java免费学习笔记(深入)”;
- 小数据量(万级以内、单值
- 大数据量或高值字段(如金额、时间戳),优先考虑
DoubleSummaryStatistics配合mapToDouble,或用BigDecimal手动算 - 别依赖
getAverage()做金融精度计算,它不保证 BigDecimal 级精度
和 Arrays.stream().summaryStatistics() 的区别
两者返回类型一样,但来源不同:Arrays.stream(new int[]{...}).summaryStatistics() 是 IntStream 自带方法,本质还是调 Collectors;而 IntStream.range(0,100).summaryStatistics() 也是同一路线。没有“更高效”的说法,底层都是同一套归约逻辑。
真正要注意的是:别混用原始类型数组和包装类集合。比如 Integer[] arr 用 Arrays.stream(arr) 得到的是 Stream<integer></integer>,必须先 mapToInt,否则编译不过——summaryStatistics() 只在 IntStream 上存在。
容易被忽略的一点:如果你统计的是对象字段,且该字段可能为 null,obj -> obj.age 会抛 NullPointerException,得先 filter 或用 Objects.requireNonNullElse 处理。









