Stream API:mapToInt()使用

在 Java 的 Stream API 中,mapToInt()的作用是将一个对象流(Stream<Integer>)转换为原始类型 int的流(IntStream)。这样做的目的主要是 ​为了提高性能和减少内存开销 。下面详细解释为什么要使用 mapToInt:


​1. 避免自动装箱/拆箱的开销​

​问题背景​

  • List<Integer>存储的是 包装类型 Integer对象,而不是原始类型 int。
  • 如果直接使用 Stream<Integer>的 sum()方法,会涉及频繁的 拆箱操作 (Integer→ int),影响性能。

​对比两种写法​

❌ 不推荐写法(使用 Stream<Integer>)

css 复制代码
// 隐式拆箱,性能较低
int sum = numbers.stream()
    .reduce(0, (a, b) -> a + b); // 每次加法都需要 Integer -> int 的拆箱

✅ 推荐写法(使用 IntStream)

scss 复制代码
// 显式转换为 IntStream,避免拆箱
int sum = numbers.stream()
    .mapToInt(Integer::intValue) // 转换为 IntStream
    .sum(); // 直接操作原始类型 int

​性能差异​:

对于大数据集(如 100 万个数字),IntStream可能比 Stream<Integer>快 ​2-3 倍。


​2. 支持专门的数值操作​

IntStream提供了 ​专为原始类型设计的高效方法,例如:

  • sum():快速求和
  • average():计算平均值
  • min()/max():找最小值/最大值
  • summaryStatistics():一次性获取统计信息
ini 复制代码
IntSummaryStatistics stats = numbers.stream()
    .mapToInt(Integer::intValue)
    .summaryStatistics();

System.out.println("总和: " + stats.getSum());
System.out.println("平均值: " + stats.getAverage());

​3. 减少内存占用​

  • Integer是对象,每个值需要额外的内存开销(约 16 字节)。
  • int是原始类型,仅需 4 字节。

当处理大量数据时,IntStream能显著减少内存使用。


​4. 其他原始类型流​

类似的优化也适用于其他原始类型:

  • mapToLong()→ LongStream
  • mapToDouble()→ DoubleStream
scss 复制代码
// 计算 long 类型总和
long longSum = numbers.stream()
    .mapToLong(Integer::longValue)
    .sum();

​何时不需要 mapToInt?​​

如果只是简单的遍历或非数值操作(如 filter、map到其他对象类型),可以直接用 Stream<Integer>:

ini 复制代码
// 不需要 mapToInt 的例子
List<String> evenNumbers = numbers.stream()
    .filter(n -> n % 2 == 0)
    .map(Object::toString)
    .collect(Collectors.toList());

​总结​

​场景​ ​推荐方式​ ​原因​
数值计算(求和、平均值) mapToInt()+ IntStream 避免拆箱、提高性能
通用操作(过滤、映射) 直接使用 Stream<Integer> 无需原始类型优化

​最佳实践​:

只要涉及 ​数值计算 ​(尤其是大规模数据),优先使用 mapToInt()/mapToLong()/mapToDouble()转换为原始类型流!

相关推荐
SL_staff17 分钟前
制造订单交付闭环实践:用跨部门计划模板解决缺料-停机-返工三角死循环
java·开源·产品
device_Any20 分钟前
接口文档写着三个字段,接口返回了五个
android·java·linux
Wang's Blog26 分钟前
Java 项目实战: 交友项目 - 小视频模块实战:访客记录、FastDFS 存储与 SpringCache 缓存
java·缓存·交友
香蕉大香蕉(06敬畏市场)36 分钟前
MySQL 单点详解(09)
java·数据库·mysql·面试·八股·大厂实习
吹什么轩1 小时前
constexpr 完全指南:从 const 的两种含义,到编译期计算的四次演进
java·前端·javascript
她的男孩1 小时前
租户 A 的验证码,却用了租户 B 的 AccessKey:Forge Admin 修跨租户短信串发
java·spring boot·saas
LabVIEW开发1 小时前
LabVIEW 局部变量与数据流:这道 CLAD 题为什么答案是 Undefined
java·开发语言·labview
文丑颜不良啊1 小时前
LeetCode1721~1740题目解析
java·leetcode
wangbing11252 小时前
监控网页项目常用英文缩写
java
麻瓜code2 小时前
双写一致性:为什么是“删缓存“,而不是“改缓存“
java·缓存·mybatis