news 2026/8/8 16:13:16

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

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
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()的初始值需要满足结合律,以确保并发结果一致。
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/31 13:35:07

Socket 编程客户端篇:Connect 隐式绑定与数据发送实战

各类资料学习下载合集 链接:https://pan.quark.cn/s/7c8c391011eb Socket 编程客户端篇:Connect 隐式绑定与数据发送实战 如果说服务器是“坐地经营”的店家(被动等待),那么客户端就是“上门拜访”的顾客(主动发起)。在 Socket 编程中,客户端的开发流程相对简洁,但其…

作者头像 李华
网站建设 2026/7/31 6:43:42

python基于django付费自习室系统的设计与实现

目录基于Django的付费自习室系统的设计与实现关于博主开发技术路线相关技术介绍核心代码参考示例结论源码lw获取/同行可拿货,招校园代理 &#xff1a;文章底部获取博主联系方式&#xff01;基于Django的付费自习室系统的设计与实现 随着教育需求的增长和学习效率要求的提升&am…

作者头像 李华
网站建设 2026/7/31 3:44:21

决策树:划分规则、剪枝方法与适用场景

决策树:划分规则、剪枝方法与适用场景 决策树(Decision Tree)算法详细介绍 一、 决策树的基本结构 二、 决策树的核心问题:如何选择划分特征? 1. 信息增益(ID3算法) (1) 前置概念:信息熵 (2) 信息增益的定义 (3) 缺点 2. 信息增益率(C4.5算法) 3. 基尼系数(C…

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

NewBie-image-Exp0.1部署教程:从零开始搭建动漫生成生产环境

NewBie-image-Exp0.1部署教程&#xff1a;从零开始搭建动漫生成生产环境 1. 引言 随着AI生成内容&#xff08;AIGC&#xff09;技术的快速发展&#xff0c;高质量动漫图像生成已成为创作者和研究者关注的核心方向之一。NewBie-image-Exp0.1 是一个专注于高保真动漫图像生成的…

作者头像 李华