273. Java Stream API - Stream 中的中间操作:Mapping 操作详解

文章目录

  • [273. Java Stream API - Stream 中的中间操作:Mapping 操作详解](#273. Java Stream API - Stream 中的中间操作:Mapping 操作详解)
      • [🧩 什么是 Mapping?](#🧩 什么是 Mapping?)
    • [🧪 示例 1:基础 `map()` 操作(注意没有终端操作!)](#🧪 示例 1:基础 map() 操作(注意没有终端操作!))
    • [✅ 示例 2:加入终端操作 `toList()`](#✅ 示例 2:加入终端操作 toList())
    • [🚀 使用 `mapToInt()`:转为 IntStream,性能更高!](#🚀 使用 mapToInt():转为 IntStream,性能更高!)
    • [📊 示例 3:统计字符串长度的各种统计数据](#📊 示例 3:统计字符串长度的各种统计数据)
    • [🧠 补充知识:map() vs. mapToInt()](#🧠 补充知识:map() vs. mapToInt())
    • [🔁 惰性求值:中间操作不会立刻执行!](#🔁 惰性求值:中间操作不会立刻执行!)
    • [🧪 对比示例:map 和 mapToInt 效果一致,但行为不同](#🧪 对比示例:map 和 mapToInt 效果一致,但行为不同)
    • [🧭 小结](#🧭 小结)

273. Java Stream API - Stream 中的中间操作:Mapping 操作详解

🧩 什么是 Mapping?

在 Stream 中,**Mapping(映射)*是指使用某个函数将流中的每个元素*转换成另一个元素,可以是不同类型,也可以是同类型。例如:

  • 把字符串转换为其长度(类型变化:String → Integer)
  • 把每个整数平方(类型不变:Integer → Integer)

🧪 示例 1:基础 map() 操作(注意没有终端操作!)

java 复制代码
List<String> strings = List.of("one", "two", "three", "four");

Function<String, Integer> toLength = String::length;

Stream<Integer> ints = strings.stream()
                              .map(toLength);

System.out.println("Done processing");

👀 输出是什么?

java 复制代码
Done processing

✅ 编译通过,也运行了,但......没有任何数据处理。

📌 原因:map() 是 中间操作 ,具有惰性求值 特性。只有在调用终端操作(如 toList()、forEach())时,流才开始执行。


✅ 示例 2:加入终端操作 toList()

java 复制代码
List<String> strings = List.of("one", "two", "three", "four");

List<Integer> lengths = strings.stream()
                               .map(String::length)
                               .toList();  // 🚀 触发执行

System.out.println("lengths = " + lengths);

输出:

java 复制代码
lengths = [3, 3, 5, 4]

🎯 这个版本中:

  • 使用 map() 把每个字符串转换为它的长度(类型变化:String → Integer)
  • 使用 toList() 把处理结果收集到列表中,从而触发整个流水线的执行

🚀 使用 mapToInt():转为 IntStream,性能更高!

如果我们不需要装箱后的 Integer 对象,而是直接处理原始 int 类型,可以使用 mapToInt() 方法。

java 复制代码
List<String> strings = List.of("one", "two", "three", "four");

IntStream lengths = strings.stream()
                           .mapToInt(String::length); // 返回 IntStream

⚠️ 和 map() 不同,这里返回的是 IntStream,一个专用于 int 的流,避免了装箱,提高性能。


📊 示例 3:统计字符串长度的各种统计数据

IntStream 提供了非常实用的终端操作 ------ summaryStatistics(),一次性获得所有统计信息。

java 复制代码
List<String> strings = List.of("one", "two", "three", "four");

IntSummaryStatistics stats = strings.stream()
                                    .mapToInt(String::length)
                                    .summaryStatistics();

System.out.println("stats = " + stats);

输出:

java 复制代码
stats = IntSummaryStatistics{count=4, sum=15, min=3, average=3.750000, max=5}

✅ 一次性获得:

  • count:元素数量
  • sum:总长度
  • min:最短长度
  • max:最长长度
  • average:平均长度

🧠 补充知识:map() vs. mapToInt()

方法 输入类型 输出类型 是否装箱 用途
map() Function<T, R> Stream<R> 是 处理任意对象类型
mapToInt() ToIntFunction<T> IntStream 否 专门用于处理整数类型,避免装箱
mapToLong() ToLongFunction<T> LongStream 否 用于处理 long 类型
mapToDouble() ToDoubleFunction<T> DoubleStream 否 用于处理 double 类型

✔ 这些 mapToX 方法适合在你需要高性能数值计算时使用,比如统计、汇总等操作。


🔁 惰性求值:中间操作不会立刻执行!

你写的 map() 并不会马上对元素做转换,Stream 就像一个懒惰的员工,直到你给它终点(终端操作),它才真正开始干活。

中间操作示例 是否触发执行? 备注
.map(...) ❌ 构建 pipeline,不执行
.filter(...) ❌ 构建 pipeline,不执行
.sorted() ❌ 构建 pipeline,不执行
.toList() ✅ 终端操作,触发执行
.forEach() ✅ 终端操作,触发执行
.count() ✅ 终端操作,触发执行

🧪 对比示例:map 和 mapToInt 效果一致,但行为不同

java 复制代码
List<String> strings = List.of("a", "bb", "ccc");

List<Integer> boxed = strings.stream()
                             .map(String::length)
                             .toList(); // 返回 List<Integer>

IntSummaryStatistics stats = strings.stream()
                                    .mapToInt(String::length)
                                    .summaryStatistics(); // 原始类型统计

🚀 boxed 版本使用的是 Integer 包装类型,适合进一步映射或收集; 📈 stats 版本用的是 IntStream,适合数值统计和计算。


🧭 小结

关键点 说明
中间操作(如 map)是惰性的 不会立即执行,必须通过终端操作触发
map 可改变类型 可将 String 映射为 Integer、Double、Long 等
使用 mapToX 避免装箱开销 高性能数值流:IntStream、LongStream、DoubleStream
summaryStatistics() 很强大 一次性获取 count、sum、min、max、average
不带终端操作的流什么也不会做 要训练学员看到 .map() 就联想到:是不是漏写了 .toList()?
相关推荐
Dovis(誓平步青云)1 分钟前
总用电下降了,为什么家庭能源看板仍然提示异常
java·开发语言·数据库·人工智能·算法·电脑·能源
程序猿乐锅2 分钟前
【从0-1学习Python | 第四篇】Python 字符串和元组
java·开发语言·笔记·后端·python·学习
Rebecca_aLi3 分钟前
码匠教育:从手工表格到脚本自动化,Python 改造工作流的思路
运维·python·自动化
开开心心就好5 分钟前
Windows视频播放器推荐,精简版体积更小
java·服务器·开发语言·eclipse·pdf·ocr·音视频
开开心心就好5 分钟前
A3的PDF怎么切成A4?拖一下分割线就行
服务器·开发语言·python·算法·pdf·ocr·tornado
小黄人软件7 分钟前
python 模块(Module)与包(Package)的区别,python xxx.py、python -m xxx 和 import xxx 三者的区别
开发语言·python
PHP实战开发录7 分钟前
PHP中文文件名为什么乱码
开发语言·php
Rain的Java大神之路27 分钟前
10 万人抢 2000 个座位,电影票选座系统怎么防超卖?一文讲透大厂高频场景题
java·后端·面试
阿里嘎多学长31 分钟前
2026-10-13 GitHub 热点项目精选
开发语言·程序员·github·代码托管
砚底藏山河33 分钟前
量化新手误区:因子计算与行情数据的工程化解耦
java·数据库·python·金融