当前位置: 首页 > news >正文

294. Java Stream API - 对流进行归约

文章目录

  • 294. Java Stream API - 对流进行归约
      • 🎯 什么是归约(Reduction)?
      • ✅ 什么是终端操作?
        • 🔔 注意事项:
    • 🧠 使用 `BinaryOperator` 对流进行归约
      • 🧪 示例一:经典求和
      • 🔁 示例二:使用 BinaryOperator 改写
      • 🧪 示例三:计算最大值(MAX)
    • ☕ Stream API 中的 reduce() 方法
      • 🧪 示例四:带初始值的 reduce(避免 Optional)
    • 📌 小结
    • 🧠 延伸思考

294. Java Stream API - 对流进行归约

🎯 什么是归约(Reduction)?

Java Stream API中,所谓的归约操作,其实就像 SQL 中的聚合操作 —— 比如SUM(),MAX()等。我们通过一个终端操作(Terminal Operation)来将流中的多个元素聚合成一个结果


✅ 什么是终端操作?

终端操作会触发整个流的执行,常见的包括:

  • collect()(如:collect(Collectors.toList())
  • reduce()(本节主角)
  • forEach()
  • count()
  • anyMatch(),allMatch(), 等
🔔 注意事项:
  1. 没有终端操作的流不会执行任何处理!
    • 如果你看到一个只调用了map()filter()但没有终端操作的流,那就是个 bug。
  2. 每个 Stream 实例只能执行一次终端操作!
    • 流一旦执行终端操作,就会“关闭”,不能再使用,否则会抛出IllegalStateException

🧠 使用BinaryOperator对流进行归约

Javareduce()方法的核心,就是使用一个二元操作符(BinaryOperator)将两个元素合并成一个,不断迭代直到只剩一个值。


🧪 示例一:经典求和

我们先用传统 for 循环来实现整数列表求和:

List<Integer>ints=List.of(3,6,2,1);intsum=ints.get(0);for(inti=1;i<ints.size();i++){sum+=ints.get(i);}System.out.println("sum = "+sum);

🟢 输出:

sum=12

🔍 这个过程就是不断把前面计算的“部分和”与下一个元素相加。


🔁 示例二:使用 BinaryOperator 改写

我们可以将“加法”逻辑抽象成一个BinaryOperator

List<Integer>ints=List.of(3,6,2,1);BinaryOperator<Integer>sum=(a,b)->a+b;intresult=ints.get(0);for(inti=1;i<ints.size();i++){result=sum.apply(result,ints.get(i));}System.out.println("sum = "+result);

🟢 输出:

sum=12

🎯 好处:只需要更换BinaryOperator,就能实现其他聚合操作!


🧪 示例三:计算最大值(MAX)

只需将 BinaryOperator 换成一个“取较大值”的函数:

List<Integer>ints=List.of(3,6,2,1);BinaryOperator<Integer>max=(a,b)->a>b?a:b;intresult=ints.get(0);for(inti=1;i<ints.size();i++){result=max.apply(result,ints.get(i));}System.out.println("max = "+result);

🟢 输出:

max=6

☕ Stream API 中的 reduce() 方法

现在让我们用Stream 的 reduce() 方法来实现相同逻辑。reduce()有多个重载版本,这里我们使用最基础的一种:

List<Integer>ints=List.of(3,6,2,1);Optional<Integer>sum=ints.stream().reduce((a,b)->a+b);sum.ifPresent(s->System.out.println("sum = "+s));

🟢 输出:

sum=12

🔎reduce()返回的是Optional<T>,因为当流为空时,没有结果。


🧪 示例四:带初始值的 reduce(避免 Optional)

List<Integer>ints=List.of(3,6,2,1);intsum=ints.stream().reduce(0,(a,b)->a+b);System.out.println("sum = "+sum);

🟢 输出:

sum=12

🎯 传入初始值后,reduce()会从这个值开始进行归约,并返回确定的类型(非 Optional)。


📌 小结

特性说明
✅ 终端操作reduce()是一种终端操作,用于聚合流元素
🔄 可变操作只需变换BinaryOperator即可进行加总、取最大、最小等操作
💡 Optional 处理不传初始值时返回Optional,可避免空流 NPE
♻️ 不可复用Stream 使用一次后即失效,请勿复用

🧠 延伸思考

  • reduce()可以用于更多复杂的聚合计算,例如拼接字符串、合并集合等。
  • 在并行流中(parallelStream()),reduce()的初始值需要满足结合律,以确保并发结果一致。
http://www.jsqmd.com/news/252627/

相关文章:

  • 百考通AI开题报告功能:智能构建研究蓝图,轻松搞定高质量开题
  • 百考通AI开题报告功能:用智能写作破解“开题难”,高效开启科研之旅
  • 农产品销售数据分析|基于Python 农产品销售数据分析系统(源码+数据库+文档)
  • 百考通AI开题报告功能:智能生成专业框架,让开题写作事半功倍
  • 基于STM32的车内环境检测和儿童滞留报警系统(开题报告)
  • ACPI!ACPIBuildProcessRunMethodPhaseCheckSta和ACPI!ACPIGetConvertToDevicePresence调试断点搜集
  • 校园食堂点餐|基于Python 校园食堂点餐系统(源码+数据库+文档)
  • python基于django校园二手交易平台管理系统
  • 百考通AI开题报告功能:告别“开题卡壳”,智能生成逻辑清晰、结构完整的专业初稿
  • 计算机毕业设计hadoop+spark+hive旅游推荐系统 旅游可视化系统 地方旅游网站 旅游爬虫 旅游管理系统 大数据毕业设计 机器学习 深度学习 知识图谱
  • YOLOv11_OBB(目标旋转框)模型从标签制作到训练推理
  • 从ACPI!AMLILoadDDB中的ACPI!SyncLoadDDB到ACPI!ACPICallBackLoad
  • 百考通AI开题报告功能:智能构建学术起点,让高质量开题触手可及
  • IP分片与组装
  • python基于django框架的健康档案网站的设计与实现
  • jQuery 版本文件及相关信息汇总
  • ARP欺骗的原理与防御措施
  • python基于django框架的大学生平时成绩管理系统 四个角色45s2bez3
  • 百考通AI开题报告功能:让开题写作从“压力源”变为“加速器”
  • springboot基于微信小程序的粤语文化传播平台的设计与开发
  • JavaScript 中实现 a.js调用 b.js函数教程
  • springboot基于微信小程序的云浮市特色农产品交易的设计与实现
  • python基于django框架的新能源汽车之家系统设计与实现
  • JavaScript 中定义全局变量的教程
  • springboot基于小程序的智能雨伞借取管理系统设计实现
  • 【实践】利用 Prettier 格式化打包后的代码?修 BUG 的隐藏神器!
  • springboot基于微信小程序的考研资源共享平台的设计与实现
  • python基于django水上乐园售票管理系统
  • 本科生开题报告PPT规范
  • python基于django人口户籍管理系统设计与实现