直接用 mapToLong 配合 sum() 可高效计算长整型总和,关键在于避免装箱开销、确保数据源适配、控制中间操作链,并注意溢出风险与函数轻量性。

直接用 mapToLong 配合 sum() 就能高效计算长整型总和,但关键在于避免装箱开销、确保数据源适配、并合理控制中间操作链。
用 mapToLong 替代 map + longValue() 转换
如果原始流是对象流(比如 Stream<integer></integer> 或 Stream<string></string>),别用 map(x -> x.longValue()) 再转成 Stream<long></long> —— 这会触发自动装箱,产生大量临时对象。应直接用 mapToLong 得到原始 LongStream:
-
list.stream().mapToLong(Integer::longValue).sum()—— 零装箱,JVM 直接处理 long 值 -
strings.stream().mapToLong(Long::parseLong).sum()—— 字符串转 long 也走原始流,不生成 Long 对象
优先从原始数组或 IntStream/DoubleStream 衍生
若源头已是基本类型数组(如 int[]),先用 Arrays.stream(arr) 得到 IntStream,再用 mapToLong 转换,比包装类流更省内存:
-
IntStream.of(1,2,3).mapToLong(i -> i).sum()—— 比Stream.of(1,2,3).mapToLong(Integer::longValue)更轻量 - 对 double 数据,用
mapToLong(Math::round)或mapToLong(d -> (long) d)显式截断,避免精度意外丢失
注意 sum() 的溢出风险
LongStream.sum() 是简单累加,不检查溢出。若数据可能超 Long.MAX_VALUE(约 9.2×10¹⁸),应改用 reduce(0L, Math::addExact),它会在溢出时抛出 ArithmeticException:
立即学习“Java免费学习笔记(深入)”;
- 安全求和:
stream.mapToLong(...).reduce(0L, Math::addExact) - 并行流下仍线程安全,
Math::addExact是纯函数,无副作用
避免在 mapToLong 中做复杂逻辑
mapToLong 函数体应保持轻量。耗时计算(如数据库查询、正则匹配)会严重拖慢流处理速度,且无法被 JIT 有效优化:
- ✅ 推荐:
obj -> obj.getId()、s -> s.length()、i -> i * 1000L - ❌ 避免:
s -> heavyParse(s).getTimestamp()—— 提前预处理或改用传统 for 循环
不复杂但容易忽略:mapToLong 本身不触发执行,必须接终止操作(如 sum、count、toArray)才会真正遍历数据。


















