跟我学 Java 8 新特性之 Stream 流(三)缩减操作

转载自   跟我学 Java 8 新特性之 Stream 流(三)缩减操作

和前面两篇文章一起服用,效果会更佳。通过对流API的基础体验Demo和关键知识点的讲解,相信大家对流API都有一定的认识了,但是流API强大的功能,可不仅仅像前面两篇文章中说的那样简单,大家应该注意到,在第二篇中,我对Stream接口进行介绍的时候,并没有把他的全部方法都进行了解析说明。

没错,从这一篇开始,那些还没有讲解的方法,很可能就开始变成我们的主角了,大家从题目上面应该知道了,本期我们要讲的是流API的缩减操作。

何为缩减操作?

我们先考虑一下min()和max(),这两个方法我们在第一篇和第二篇中均有提到,其中min()是返回流中的最小值,而max()返回流中最大值,前提是他们存在。

他们之间的特点是什么?

①都返回了一个值

②由一可知,他们是终端操作。

如果我们用流API的术语来形容前面这两种特性的结合体的话,它们代表了缩减操作。因为每个缩减操作都把一个流缩减为一个值,好比最大值,最小值。当然流API,把min()和max(),count()这些操作称为特例缩减。

即然说到了特例,肯定就有泛化这种概念了,他就是reduce()方法了,其实第二篇当中,他已经出现过了,只是当时我没有去强调他。

public interface Stream<T> extends BaseStream<T, Stream<T>> {//、、、忽略其他无关紧要的元素
T reduce(T identity, BinaryOperator<T> accumulator);
Optional<T> reduce(BinaryOperator<T> accumulator);
<U> U reduce(U identity,BiFunction<U, ? super T, U> accumulator, BinaryOperator<U> combiner);
}

Stream接口定义了三个版本的reduce(),我们先使用前面两个,

T reduce(T identity, BinaryOperator<T> accumulator);//1
Optional<T> reduce(BinaryOperator<T> accumulator);//2

第一个版本返回的是一个T类型的对象,T代表的是流中的元素类型!第二个版本是返回一个Optional类型对象。对于这两种形式,accumulator是一个操作两个值并得到结果的函数。在第一个版本当中,identity是这样一个值,对于涉及identity和流中任意的累积操作,得到的结果就是元素自身,没有任何改变。比如,如果是加法,他就是0,如果是乘法他就是1。

其中的accumulator是一个BinaryOperator的类型,他是java.util.function包中声明的函数式接口,它扩展了BiFunction函数式接口.

@FunctionalInterface
public interface BinaryOperator<T> extends BiFunction<T,T,T> {}@FunctionalInterface
public interface BiFunction<T, U, R> {R apply(T t, U u);//notice
}

BiFunction接口中的apply()方法的原型在 //notice。其中R指定了结果的类型,T,U分别是第一参数的类型和第二个参数的类型,因此apply()对他的两个操作数(t,u)应用到同一个函数上,并返回结果,而对BinaryOperator来说,他在扩展 BiFunction时,指定了所有的类型参数都是相同的T,因此对于BinaryOperator函数式接口的apply来说,他也就变成了 T apply(T t, T u),此外,还有一个需要注意的地方是,在应用reduce()时,apply()的第一个参数t,包含的是一个结果,u包含的是下一个元素。在第一次调用时,将取决于使用reduce()的版本,t可能是单位值,或者是前一个元素。

缩减操作的三个约束

  • 无状态

  • 不干预

  • 关联性

无状态,这里可不是LOL的那个无状态,毕竟他退役了。相信读过第二篇文章的同学已经很容易理解了,简单来说无状态就是每个元素都被单独地处理,他和流中的其它元素是没有任何依赖关系的。不干预是指操作数不会改变数据源。最后,操作必须具有关联性,这里的关联性是指标准的数学含义,即,给定一个关联运算符,在一系列操作中使用该运算符,先处理哪一对操作数是无关紧要的。比如,(1 * 2) * 3 <===> 1 * (2 * 3)。 

其中关联性,在并行流中,是至关重要的。下面我用一个简单的例子带着大家实战一下泛化缩减操作reduce()的使用。

public class Main {public static void main(String[] args) {learnStream();}private static void learnStream() {List<Integer> lists = new ArrayList<>();lists.add(1);lists.add(2);lists.add(3);lists.add(4);lists.add(5);lists.add(6);Optional<Integer> sum = lists.stream().reduce((a, b) -> a + b);if (sum.isPresent()) System.out.println("list的总和为:" + sum.get());//21//<====> lists.stream().reduce((a, b) -> a + b).ifPresent(System.out::println);Integer sum2 = lists.stream().reduce(0, (a, b) -> a + b);//21System.out.println("list的总和为:" + sum2);Optional<Integer> product = lists.stream().reduce((a, b) -> a * b);if (product.isPresent()) System.out.println("list的积为:" + product.get());//720Integer product2 = lists.stream().reduce(1, (a, b) -> a * b);System.out.println("list的积为:" + product2);//720}
}

这个Demo主要是计算了一个list里面的总和,积的操作,大家可以和传统的算总和,积的方法进行对照,比一比衡量一下就有自己的答案了。但是如果你以为流API仅此而已,那你就错了。

越是后面的东西,就越装B,我在刚知道他们的时候,反正是被吓了一跳的,但这些都是后话了,现在我们来详解一下Demo,并给出扩展的方向:我们这个例子主要是用了lambda表达式对list进行了求和,求积,对于第一个版本为说,求和的时候,identity的值为0,求积的时候它的值为1,强烈建议你们自己感受一下identity的变化对整个结果的变化产生什么 的影响,改变一下identity的值,再运行一下,你就有结果了,另一个扩展点是:

Integer product3 = lists.stream().reduce(1, (a, b) -> {if (b % 2 == 0) return a * b; else return a;//这里你可以为所欲为!
});System.out.println("list的偶数的积为:" + product3);//48

小结一下

对于流的缩减操作来说,主要要知道,他只返回一个值,并且它是一个终端操作,然后还有的就是要知道缩减操作的三个约束了,其实最重要的就是无状态性和关联性了.这一小节要说的,也就这么多了,应该很容易就把他收到自己的技能树上面了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/325650.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

JS中字符串的常用方法

<!DOCTYPE html> <html><head><meta charset"UTF-8"><title></title><script type"text/javascript">//创建一个字符串var str "Hello Atguigu";/** 在底层字符串是以字符数组的形式保存的* ["…

使用Angular 4、Bootstrap 4、TypeScript和ASP.NET Core开发的Apworks框架案例应用

最近我为我自己的应用开发框架Apworks设计了一套案例应用程序&#xff0c;并以Apache 2.0开源&#xff0c;开源地址是&#xff1a;https://github.com/daxnet/apworks-examples&#xff0c;目的是为了让大家更为方便地学习和使用.NET Core、最新的前端开发框架Angular&#xff…

C#使用集合组织相关数据

一、为什么使用集合&#xff1f; 数组的长度是固定的&#xff0c;对数组中的元素进行动态添加和删除的时候很麻烦。集合可以更好的进行对元素添加和删除 二、ArrayList集合&#xff1a; 1.类似于数组&#xff0c;但是可以直观的动态维护。 2.位于System.Collections命名空间里面…

IntelliJ IDEA 最常用配置详细图解,新手入门必看

转载自 IntelliJ IDEA 最常用配置详细图解&#xff0c;新手入门必看 刚刚使用IntelliJ IDEA 编辑器的时候&#xff0c;会有很多设置&#xff0c;会方便以后的开发&#xff0c;磨刀不误砍柴工。 比如&#xff1a;设置文件字体大小&#xff0c;代码自动完成提示&#xff0c;版…

MyBatis(延迟加载 缓存)

mybatis目录 一对一延迟加载 1.在SqlMapConfig.xml中配置setting标签 2.在IAccoutDao.xml中配置association标签 3.测试类 4.成功运行 一对多延迟加载 2.在IUserDao.xml中配置collection标签 缓存 一级缓存 二级缓存 1.SqlMaoConfig.xml中 2.在需要使用二级缓存的实体类的mapp…

JS函数中的arguments

<!DOCTYPE html> <html><head><meta charset"UTF-8"><title></title><script type"text/javascript">/** 在调用函数时&#xff0c;浏览器每次都会传递进两个隐含的参数&#xff1a;* 1.函数的上下文对象 this…

剑英的区块链学习手记(二)

孙子说&#xff0c;知己知彼&#xff0c;百战不殆。 咱是通过小蚁学习区块链技术的。 开工之前&#xff0c;先了解一下小蚁的资料家族。 小蚁网站 https://www.antshares.org/ 小蚁源码 https://github.com/AntShares 小蚁SDK源码 https://github.com/ANTSHARESSdk 比较集…

PhotoShop基础知识

一、PhotoShop&#xff1a; 1.是由Adobe Systems开发和发行的专门用于图形图像处理的软件 2.优点&#xff1a;绘制或者处理后的图像&#xff0c;颜色鲜明、形象生动&#xff0c;能够给观者很好的视觉效果。 二、PhotoShop软件应用领域&#xff1a; 1.在平面设计中的应用 2.在插…

跟我学 Java 8 新特性之 Stream 流(二)关键知识点

转载自 跟我学 Java 8 新特性之 Stream 流&#xff08;二&#xff09;关键知识点 我们的第一篇文章&#xff0c;主要是通过一个Demo&#xff0c;让大家体验了一下使用流API的那种酣畅淋漓的感觉。如果你没有实践&#xff0c;我还是再次呼吁你动手敲一敲&#xff0c;自己实实…

mybatis使用注解开发

Mybatis目录 注解开发的crud 1.IUserDao接口中使用注解 2.测试类 注解开发的多表查询 多对一&#xff08;一对一&#xff09; 1.IAccountDao接口中使用注解 2.Account类中&#xff08;从表类&#xff09; 3.测试类 一对多&#xff08;多对多&#xff09; 1.IUserDao接口中使用…

Build 2017 | 微软开发者大会临近,今年的主题是边缘计算

200 多家明星企业&#xff0c;20 位著名投资机构顶级投资人共同参与&#xff01;「新智造成长榜」致力于发掘 AI 领域有 “三年十倍” 成长潜力的创新公司&#xff0c;下一波 AI 独角兽&#xff0c;会有你么&#xff1f;点击加入&#xff01; 雷锋网按&#xff1a;微软首席执行…

Photoshop的基本操作

一、缩放工具 1.缩放工具相当于放大镜和缩小镜&#xff0c;从视觉上改变图像的大小&#xff0c;但实际尺寸并没有改变。 2.快捷键&#xff1a;z或者按住alt鼠标滑轮上滑&#xff08;放大&#xff09;、下滑&#xff08;缩小&#xff09; 二、抓手工具&#xff1a; 1.当图片放大…

JDBC8.0 URL配置

Spring中即成DBUtils <property name"jdbcUrl" value"jdbc:mysql://localhost:3306/eesy_mybatis?useUnicodetrue&amp;characterEncodingUTF-8&amp;serverTimezoneUTC"></property>

王者齐聚!Unite 2017 Shanghai 日程讲师全揭晓

汇聚了来自全球的 Unity开发者、发行商、培训家及爱好者的 Unite 2017 Shanghai 即将于于 5 月 11 日&#xff0d;13日在上海国际会议中心隆重举行。Unite 大会是由 Unity 举办的全球开发者大会&#xff0c;至今已有 10 年历史&#xff0c;并已成为游戏行业、VR/AR 行业最具权威…

批评?惩罚?

批评&#xff1f;惩罚&#xff1f;最近一直在听王晓春老师的《做一个专业的班主任》&#xff0c;并且上次在校内分享教学经验和技巧的时候&#xff0c;也推荐给其他的老师看了。我一般都是在上班的路上听&#xff0c;王老师的很多观点确实值得我们深思&#xff0c;但是&#xf…

屌炸天,Oracle 发布了一个全栈虚拟机 GraalVM,支持 Python

转载自 屌炸天&#xff0c;Oracle 发布了一个全栈虚拟机 GraalVM&#xff0c;支持 Python 前阵子&#xff0c;Oracle 发布了一个黑科技 "GraalVM"&#xff0c;号称是一个全新的通用全栈虚拟机&#xff0c;并具有高性能、跨语言交互等逆天特性&#xff0c;真有这么…

IDEA 配置Maven项目

https://blog.csdn.net/qq_41799219/article/details/90782162

就业形势如此的严峻,你为何不努力?

就业形势如此的严峻&#xff0c;你们有何理由不努力&#xff1f;今天&#xff0c;围绕就业的问题展开个话题吧。马上&#xff0c;18级1班就要出去就业了&#xff0c;以前带的17级3班三期的时候学生的状态都比较积极&#xff0c;自己知道自己的实力&#xff0c;我和就业老师、班…

涨姿势,图文带你了解 8 大排序算法

转载自 涨姿势&#xff0c;图文带你了解 8 大排序算法 排序算法可以分为内部排序和外部排序&#xff0c;内部排序是数据记录在内存中进行排序&#xff0c;而外部排序是因排序的数据很大&#xff0c;一次不能容纳全部的排序记录&#xff0c;在排序过程中需要访问外存。 常见…

React中分页错误

因为save是异步方法 直接从model中取最新的数据