longstream和intstream是java 8为long、int提供的原始类型特化流,避免装箱开销;必须用longstream当数据超出int范围(如时间戳),其sum()返回long、max()返回optionallong,且boxed()会破坏性能优势。

LongStream 和 IntStream 是什么,为什么不能直接用 Stream
它们是 Java 8 引入的原始类型特化流,专为 long 和 int 设计,绕过对象装箱(Long、Integer),避免在大量数值计算中反复创建临时对象。用 Stream<long></long> 处理一千万个整数,GC 压力会明显升高,而 LongStream 在底层用数组存原始值,没这层开销。
什么时候必须用 LongStream 而不是 IntStream
当数据范围超出 int(−2³¹ 到 2³¹−1)时,比如时间戳、数据库主键、大文件偏移量。用 IntStream.range(0, 3_000_000_000) 会直接编译失败——上限超了;但 LongStream.range(0, 3_000_000_000L) 没问题。
-
LongStream的range和rangeClosed接收long参数,IntStream只接受int - 聚合操作如
sum()返回类型不同:IntStream.sum()返回int,LongStream.sum()返回long,溢出行为也不一样(int会静默回绕,long同理,但范围更大) - 和
Optional交互时:IntStream.max()返回OptionalInt,LongStream.max()返回OptionalLong,不能混用
常见误用:mapToInt / mapToLong 之后忘了终止操作
写 stream.mapToLong(x -> x.id).filter(y -> y > 100) 后直接赋值给 LongStream 变量没问题,但若想立刻取值,必须加终止操作,比如 .findFirst() 或 .toArray()。否则只是构建了流水线,什么都没执行。
- 错误示例:
LongStream s = list.stream().mapToLong(Item::getId).filter(id -> id > 100);—— 这行不报错,但没触发计算 - 正确用法:
long first = list.stream().mapToLong(Item::getId).filter(id -> id > 100).findFirst().orElse(-1L); - 注意
findFirst()返回OptionalLong,不能用.get()直接取,得用orElse或ifPresent
性能陷阱:boxed() 一调就破功
LongStream.boxed() 会把每个 long 装箱成 Long,瞬间回到起点。它只该用于必须交出 Stream<long></long> 的极少数接口(比如某些老库要求),日常开发中基本不需要。
立即学习“Java免费学习笔记(深入)”;
- 别为了“统一类型”把
LongStream转成Stream<long></long>再处理——后续所有map、filter都变成对象操作 - 如果要打印调试,用
forEach(System.out::println),不要先boxed()再forEach - 并行流下装箱开销更明显:
LongStream.parallel().boxed().map(...)可能比串行Stream<long></long>还慢
原始流的价值全在“不装箱”,一旦跨过那条线,优化就归零。很多人写到一半顺手加个 boxed(),自己都意识不到已经白忙活了。









