IntStream.summaryStatistics()返回计数、总和、最小值、最大值和平均值;空流时getMin()/getMax()抛NoSuchElementException,getAverage()返回NaN,getSum()和getCount()返回0。

IntStream.summaryStatistics() 能返回哪些统计值
IntStream.summaryStatistics() 返回一个 IntSummaryStatistics 实例,它内部缓存了计数、总和、最小值、最大值和平均值(double 类型)——不是实时计算,而是流遍历过程中一次性累积完成。这意味着你不需要分别调用 sum()、max() 等多次终端操作,避免重复遍历。
必须注意的空流陷阱
如果流为空,getMin() 和 getMax() 会抛出 NoSuchElementException,而 getAverage() 返回 NaN,getSum() 返回 0,getCount() 返回 0。这不是 bug,是设计如此。
- 务必先检查
getCount() > 0再调用getMin()或getMax() - 不要直接对
getAverage()做算术运算(比如加 1),先用Double.isFinite()判断是否有效 - 若业务上空流需默认值,建议用
Optional.ofNullable(...).orElse(...)封装,而非硬写 try-catch
和单独调用 min()/max()/average() 的性能差异
单独调用 min()、max()、average() 各自触发一次流遍历,时间复杂度 O(3n);而 summaryStatistics() 只遍历一次,O(n),且对象创建开销极小。尤其在并行流中,差异更明显——并行 summaryStatistics() 自动合并各分段统计结果,而多次调用可能因流已关闭报 IllegalStateException。
- 适合:需同时获取 ≥3 个聚合值的场景
- 不适合:只取最大值或只取平均值这种单指标需求(语义更清晰,且 JIT 可能优化得更好)
- 注意:并行流下
IntSummaryStatistics的toString()输出不保证字段顺序,但各字段值正确
一个安全可用的实操示例
下面这段代码处理任意 int[],兼容空数组,并显式防御所有边界情况:
int[] data = {1, 3, 2, 5};
IntSummaryStatistics stats = IntStream.of(data).summaryStatistics();
if (stats.getCount() == 0) {
System.out.println("空数据");
} else {
System.out.printf("count=%d, sum=%d, min=%d, max=%d, avg=%.2f%n",
stats.getCount(),
stats.getSum(),
stats.getMin(),
stats.getMax(),
stats.getAverage()
);
}
别忘了:平均值是 double,格式化输出时容易忽略精度问题;如果下游需要整数均值,应明确用 (int) Math.round(stats.getAverage()),而不是强制截断。











