news 2026/6/20 1:49:47

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/6/18 20:58:45

Laravel 13权限升级了?多模态控制你真的懂吗?

第一章&#xff1a;Laravel 13权限系统演进与多模态控制概述Laravel 13在权限管理方面进行了结构性优化&#xff0c;引入了更灵活的多模态控制机制&#xff0c;支持基于角色、策略和属性的复合鉴权模式。这一演进使得开发者能够更精细地控制资源访问&#xff0c;适应复杂业务场…

作者头像 李华
网站建设 2026/6/20 10:16:49

PageAdmin:为企业提供全方位数字化转型解决方案

Pageadmin 主要专注于网站内容管理系统、SSO 单点登录、统一身份认证平台&#xff0c;低代码平台系统的研发&#xff0c;致力于为网站建设和统一数字化信息平台提供企业级的解决方案 pagedmin 产品线 1、网站内容管理系统 于 2008 年发布第一个免费版本&#xff0c;已和全国各地…

作者头像 李华
网站建设 2026/6/20 11:50:17

告别冗余代码:PHP集成GraphQL时类型定义复用的7种高级策略

第一章&#xff1a;GraphQL的PHP类型定义复用在构建复杂的GraphQL API时&#xff0c;PHP后端开发者常面临类型重复定义的问题。通过合理的设计模式与工具支持&#xff0c;可以有效实现类型定义的复用&#xff0c;提升代码可维护性并减少冗余。共享类型定义 将常用的GraphQL类型…

作者头像 李华
网站建设 2026/6/19 9:15:41

【专家级避坑指南】:纤维协程调试中最常见的5个陷阱与应对策略

第一章&#xff1a;纤维协程的调试工具 在现代高并发系统中&#xff0c;纤维协程&#xff08;Fiber-based Coroutines&#xff09;因其轻量级与高效调度特性被广泛采用。然而&#xff0c;协程的异步非阻塞特性和运行时动态切换机制也带来了调试复杂性的挑战。为有效定位挂起、死…

作者头像 李华
网站建设 2026/6/20 11:12:28

【江鸟中原】集光鸿蒙项目开发

集光 - 智能笔记应用 &#x1f4f1; 应用简介 集光是一款专为HarmonyOS生态设计的智能笔记应用&#xff0c;提供安全、高效、美观的笔记管理体验。应用集成了华为账号服务&#xff0c;支持多种笔记编辑功能&#xff0c;让您的创意和想法得到完美记录。 ✨ 核心特性 &#x…

作者头像 李华