使用stream.maptoint前需确保映射结果为int,否则可能抛nullpointerexception;sum()返回int且不检测溢出,大数据量时建议用maptolong+sum();空list调用sum()安全,返回0;推荐collectors.summingint提升语义清晰度。

用 Stream.mapToInt 前必须确保映射结果是 int
直接调 mapToInt 却传了个 Integer 或 null,会抛 NullPointerException 或编译失败。它只接受返回 int 的函数(ToIntFunction),不是任意对象转 int 的万能胶水。
- 如果属性是
Integer类型,用.mapToInt(obj -> obj.getProperty() != null ? obj.getProperty() : 0)防空 - 如果属性是包装类但可能为
null,别偷懒写.mapToInt(Obj::getProperty)—— 这里会触发自动拆箱,null就崩 - 若属性本身是基本类型(如
int字段),可安全用方法引用:.mapToInt(MyObj::getScore)
sum() 返回的是 int,溢出不报错
sum() 是 IntStream 终止操作,结果是原始 int。它不会检测整数溢出,加着加着就变负数了,而且完全静默。
- 数据量大或值本身较大时(比如统计毫秒时间戳总和、金额累加),优先考虑
mapToLong+sum() - 例如:
list.stream().mapToLong(MyObj::getAmount).sum(),返回long,容错空间大得多 - 真要严格防溢出,得自己用
reduce配合Math.addExact,但性能有损,一般场景没必要
空 List 调用 sum() 安全,返回 0
这点很省心:IntStream.empty().sum() 明确定义为返回 0,不用提前判空。
- 所以
list.stream().mapToInt(...).sum()对空List是安全的,结果就是0 - 但注意:如果中间映射逻辑抛异常(比如上面说的
null拆箱),那空不空都救不了你 - 别为了“看起来严谨”包一层
Optional.ofNullable(list).orElse(Collections.emptyList())—— 多余
替代方案:用 Collectors.summingInt 更语义化
如果你只是求和,不打算在 stream 后续接其他数值操作(比如平均、最大值),用收集器更直白,也更容易改造成带条件过滤的版本。
立即学习“Java免费学习笔记(深入)”;
- 写法:
list.stream().collect(Collectors.summingInt(MyObj::getScore)) - 好处是意图清晰,且天然支持与
filter组合,比如只加正分:.filter(obj -> obj.getScore() > 0).collect(...) - 性能和
mapToInt + sum几乎无差别,JVM 优化后基本一致
null,或者没意识到 int 总和会悄无声息地溢出。这两个点比选 sum() 还是 summingInt 重要得多。










