news 2026/4/12 3:26:05

270. Java Stream API - 从“怎么做”转向“要什么结果”:声明式编程的优势

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
270. Java Stream API - 从“怎么做”转向“要什么结果”:声明式编程的优势

文章目录

    • 270. Java Stream API - 从“怎么做”转向“要什么结果”:声明式编程的优势
      • 🎯 目标任务
      • 🧱 传统命令式写法(Java 代码)
      • 💡 思维实验:如果 Collection 有 map 和 filter 会怎样?
      • ❌ 性能陷阱:中间集合的隐性开销
    • ✅ 为什么是 Stream,而不是 Collection?
      • 🌊 Stream 的关键特性:**不存储数据,只描述处理过程**
      • 🧠 懒加载(Lazy Evaluation):终端操作才“开水龙头”
      • ⚙️ 示例:短路操作节省时间
    • 📊 总结:为什么 map/filter 不属于 Collection 接口?
    • 🧵 Stream API 的流水线模型:终端操作才“触发机器运转”
    • 📘 实操建议(练习题):

270. Java Stream API - 从“怎么做”转向“要什么结果”:声明式编程的优势

🎯 目标任务

我们要计算一个城市列表中,人口超过 10 万的城市总人口数


🧱 传统命令式写法(Java 代码)

recordCity(intpopulation){}List<City>cities=List.of(newCity(100_000),newCity(200_000),newCity(500_000));intsum=0;for(Citycity:cities){intpopulation=city.population();if(population>100_000){sum+=population;}}System.out.println("Sum = "+sum);// 输出:700000

这段代码很好地完成了目标,但是命令式的——一步一步告诉程序要做什么。


💡 思维实验:如果 Collection 有 map 和 filter 会怎样?

假设我们扩展Collection接口,给它添加map()filter()方法,并且它们返回的是Collection

Collection<Integer>populations=cities.map(city->city.population());Collection<Integer>filteredPopulations=populations.filter(p->p>100_000);intsum=filteredPopulations.sum();

看起来很“链式”,很优雅,但有一个严重问题每一步都要创建中间集合!


❌ 性能陷阱:中间集合的隐性开销

  • map()会遍历所有城市,并创建一个新的集合保存每个城市的人口数。
  • filter()会再遍历这个人口集合,选出符合条件的。
  • sum()会再遍历过滤结果做加总。

👉 如果处理上百万城市对象,那么这会造成大量内存分配和垃圾回收压力

而传统的for循环是一边遍历、一边判断、一边累加的,没有任何中间结构的创建


✅ 为什么是 Stream,而不是 Collection?

🌊 Stream 的关键特性:不存储数据,只描述处理过程

intsum=cities.stream().mapToInt(City::getPopulation)// 先映射成人口数.filter(p->p>100_000)// 筛选出人口超 10 万的.sum();// 聚合求和(终端操作)

在这段代码中:

  • 没有中间集合产生;
  • .mapToInt().filter()都是中间操作,只是“排管道”;
  • .sum()终端操作,才真正触发数据流动和计算。

🧠 懒加载(Lazy Evaluation):终端操作才“开水龙头”

  • Stream就像“工厂流水线”,每个操作(map/filter)都是一个加工环节;
  • 只有当你调用.sum().collect()等终端操作时,才真的开始处理每个数据;
  • 每个数据只“走一次管道”:

💡 不是“先映射完所有人口” ➝ “再筛选” ➝ “再加总”,
而是:每个城市 ➝ 映射 ➝ 判断是否保留 ➝ 累加(即一条龙服务🚀)。


⚙️ 示例:短路操作节省时间

需求:判断是否存在人口超过 100_000 的城市

传统 Collection 风格必须遍历:

booleanexists=cities.map(City::population).filter(p->p>100_000).anyMatch(p->true);// 已经浪费了两步处理

而用 Stream 可以做到只看第一个符合条件的城市

booleanexists=cities.stream().anyMatch(c->c.getPopulation()>100_000);

💥 一旦遇到满足条件的城市,就立即返回true,后续不再处理!


📊 总结:为什么 map/filter 不属于 Collection 接口?

方式map/filter 返回类型是否创建中间集合是否惰性求值是否支持短路
Collection.map()Collection✅ 会创建❌ 否❌ 否
Stream.map()Stream❌ 不创建✅ 是✅ 是(如 anyMatch)

👉 正因为Collection 是数据容器,而Stream 是操作流水线,所以map()filter()被设计在Stream而非Collection


🧵 Stream API 的流水线模型:终端操作才“触发机器运转”

操作类型举例描述
中间操作map(),filter(),sorted()返回 Stream,不触发计算
终端操作sum(),collect(),forEach()返回非 Stream,触发计算

📘 实操建议(练习题):

  1. 使用stream()实现:计算人口超过 200_000 城市的平均人口;
  2. 统计有多少个城市符合人口 > 100_000;
  3. 判断是否所有城市人口都 > 50_000。
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/8 11:35:20

LobeChat是否支持OAuth登录?第三方鉴权集成进展

LobeChat是否支持OAuth登录&#xff1f;第三方鉴权集成进展 在构建现代AI对话系统时&#xff0c;身份认证早已不再是“有无”的问题&#xff0c;而是“如何做得更安全、更灵活、更贴近组织架构”的工程挑战。随着LobeChat这类开源聊天界面逐渐被用于团队协作和企业内部助手场景…

作者头像 李华
网站建设 2026/4/9 22:29:20

如何在笔记本上运行50量子比特模拟?:不为人知的内存压缩黑科技

第一章&#xff1a;量子计算的模拟量子计算的模拟是研究和开发量子算法的重要手段。由于当前真实量子计算机仍处于发展阶段&#xff0c;资源有限且易受噪声干扰&#xff0c;科研人员广泛依赖经典计算机来模拟量子系统的行为。通过构建量子态的数学模型&#xff0c;并在经典硬件…

作者头像 李华
网站建设 2026/4/9 3:44:53

揭秘低代码平台事件绑定难题:3步实现无缝交互逻辑

第一章&#xff1a;低代码组件的事件在低代码平台中&#xff0c;组件事件是实现交互逻辑的核心机制。通过监听用户操作或系统行为触发的事件&#xff0c;开发者可以快速构建动态响应的界面&#xff0c;而无需编写大量底层代码。事件的基本概念 事件是组件在特定条件下发出的信号…

作者头像 李华
网站建设 2026/4/8 9:58:18

别再盲目聚类了!空间转录组R语言最优算法选择指南

第一章&#xff1a;空间转录组细胞聚类的核心挑战空间转录组技术结合了基因表达谱与组织空间位置信息&#xff0c;为解析组织微环境提供了前所未有的视角。然而&#xff0c;在对空间转录组数据进行细胞聚类时&#xff0c;研究者面临多个核心挑战&#xff0c;这些挑战直接影响聚…

作者头像 李华
网站建设 2026/4/11 18:16:46

太月香学新书《中国传统香学》首发亮相

12月11日&#xff0c;第12届全球外交官中国文化之夜在京举办。该活动由上午的“全球品牌发展暨中国品牌出海论坛”及晚上的“中国文化之夜”组成。活动旨在促进各国驻华外交官、文化学者及企业精英间的文化交流与合作&#xff0c;推动文明互鉴与民心相通。 在“全球品牌发展暨…

作者头像 李华
网站建设 2026/4/11 15:35:35

2025冬暖影展奔赴广州,以光影开启时空对话

本周&#xff0c;全国艺联2025“艺术新作冬暖主题影展”携十部尚未公映的国产艺术佳作翩然落地广州。12月9日至11日&#xff0c;《爷爷奶奶那些事》、《燃比娃》、《长夜将尽》三部展映影片的主创团队惊喜现身映后交流环节&#xff0c;与羊城观众共同开启跨越时空的真挚对话&am…

作者头像 李华