Collectors.summarizingInt 返回 IntSummaryStatistics 对象而非原始 int,需先保存为变量再调用 getMax()、getAverage() 等方法,直接链式调用 .max() 会编译失败。
summarizingInt 返回的是 IntSummaryStatistics,不是数字
很多人调用
后直接想用
却报错,其实是没意识到它返回的是一个封装对象,不是原始 int。这个对象里才存着你真正要的统计值。
常见错误现象:
写完就试图在后面链式调用
或
—— 编译不通过,因为
没有这些方法名(正确是
、
)。
必须先保存结果到变量,再调用
/
/
/
/
返回
,注意空流时返回
(不是
),这点和
不同
如果流为空,
和
会返回
和
—— 这是设计行为,不是 bug,但容易误判
空流时的极值要单独判断,不能直接信 getMin/getMax
比如对空
调用
,得到的
的
是
,
是
。这显然不是业务想表达的“无数据”。
正确做法是先检查
,再决定是否取极值:
summarizingInt 只支持 int,别和 summarizingLong/Double 混用
类型不匹配会导致编译失败或隐式截断。比如对
值强行用
,会触发
强制转换,可能溢出。
输入是
或
?用
输入是
或
?用
没有泛型推导魔法——函数参数类型必须和收集器类型一致,否则编译不过
性能上三者无差别,选错只是逻辑错误,不是慢的问题
替代方案:需要部分统计量时,summarizingInt 可能过度
如果只要平均值和总数,用
+
并行收集反而更清晰;如果还要做分组统计,
配合
是好选择,但要注意嵌套后类型变深。
单次遍历确实省事,但可读性未必高——尤其当后续只用其中一两个字段时
如果统计逻辑后续要扩展(比如加标准差),
不提供,得自己算或换库
它不支持自定义精度控制(比如平均值保留两位小数),得靠外部格式化
真正容易被忽略的是空流时的极值语义——它不是“未定义”,而是有确定但反直觉的返回值,业务代码里漏掉判断,上线后可能在边缘 case 里悄悄出错。
Collectors.summarizingInt.getMax()stream.collect(Collectors.summarizingInt(x -> x)).max().average()IntSummaryStatisticsgetMax()getAverage()getMin()getMax()getAverage()getSum()
getAverage()double0.0NaNOptionalDoublegetMin()getMax()Integer.MAX_VALUEInteger.MIN_VALUEListsummarizingIntIntSummaryStatisticsgetMin()2147483647getMax()-2147483648getCount() == 0IntSummaryStatistics stats = list.stream()
.collect(Collectors.summarizingInt(Integer::intValue));
if (stats.getCount() == 0) {
// 处理空情况:抛异常、返回 Optional.empty()、或设默认值
} else {
int min = stats.getMin();
int max = stats.getMax();
double avg = stats.getAverage();
}longsummarizingIntlong → intlongLongCollectors.summarizingLong(Long::longValue)doubleDoubleCollectors.summarizingDouble(Double::doubleValue)Collectors.averagingIntCollectors.counting()summarizingIntgroupingByIntSummaryStatisticsgetCount()