java8学习之Stream深度解析与源码实践

摘要:
为了继续学习流式传输,让我们首先解释流式传输的特性:1.集合提供了一种新的流()方法。接下来,尝试将流转换为列表。我该怎么做?由于流集合可以转换为列表,我们还研究了第二个复杂且过载的流集合(Supplier<R>Supplier,BiConsumer<R,?

 继续对流进行学习,首先先说明一下流的特点:

1、Collection提供了新的stream()方法。

2、流不存储,通过管道的方式获取值。

3、本质是函数式的,对流的操作会生成一个结果,不过并不会修改底层的数据源,集合可以作为流的底层数据源。
其中需要注意标红的说明,也就是说对于流操作它的源数据是不会被更改的,另外还有一点需要有一个认知:对于一个流可能有若干个中间操作,对于这些操作并非降低了整体的执行性能,反而会有提升,比如说增加了三个中间操作,可能感受会有三次循环,但是实际并非是咱们想象的这样,这个随着流的不断深入就会体会到这点的。

4、延迟查找,很多流操作(过滤filter、映射map、排序sort等)都可以延迟实现。

接着再用代码来进行操练,首先构建一个Stream对象,这里用一个集合的方式构建,然后将它转换数组,如下:

java8学习之Stream深度解析与源码实践第1张

下面具体看一下该方法的定义:

java8学习之Stream深度解析与源码实践第2张

而IntFunction的接口原型如下:

java8学习之Stream深度解析与源码实践第3张

那这个参数如何写呢?当然可以用Lambda表达式啦,那具体如何表示呢?看下面:

java8学习之Stream深度解析与源码实践第4张

其实对于这个toArray()参数还可以改用方法引用,那如何写呢?

java8学习之Stream深度解析与源码实践第5张

接下来想办法将Stream转换为一个List,如何搞呢?

java8学习之Stream深度解析与源码实践第6张

所以转换如下:

java8学习之Stream深度解析与源码实践第7张

初略查看一下上面用到的Collectors类,发现其实它是Java1.8针对集合提供的一个工具类,里面包含若干个实现的工具方法,如下:

java8学习之Stream深度解析与源码实践第8张

那看一下用到的toList()方法的实现:

java8学习之Stream深度解析与源码实践第9张

java8学习之Stream深度解析与源码实践第10张

而回到Stream.collect()方法,它还有另外一个比较复杂的方法重载,如下:

java8学习之Stream深度解析与源码实践第11张

点进去查看一下该方法的定义:

java8学习之Stream深度解析与源码实践第12张

是不是跟第一个collect()方法中使用的Collectors.toList()方法的具体实现中CollectorImpl中的参数一样?既然用stream.collect(Collectors.toList())能达到转换成List的目的,还研究第二种比较复杂重载的stream.collect(Supplier<R> supplier,BiConsumer<R, ? super T> accumulator,BiConsumer<R, R> combiner)干嘛呢?因为要想搞清楚stream.collect(Collectors.toList())就必须理解这种比较复杂的collect(),因为Collectors.toList()最终的实现就是跟比较复杂的collect()的实现类似,所以说接下来好好理解一下这个比较复杂的方法,确实是不太好理解,先读下它的javadoc:

java8学习之Stream深度解析与源码实践第13张

那什么叫"mutable reduction可变的汇聚"呢?接着看解释:

java8学习之Stream深度解析与源码实践第14张

不晓得说的是什么意思,下面有个例子对其进行说明:

java8学习之Stream深度解析与源码实践第15张

那如何调用这种复杂的collect()方法来实现stream.collect(Collectors.toList())同样的效果呢?实现过程会要复杂很多,但是这个复杂的过程是对其内部了解起到很大的作用,所以有必要折腾一下:

首先第一个参数传递的它:

java8学习之Stream深度解析与源码实践第16张

而Supplier接口的原型是:

java8学习之Stream深度解析与源码实践第17张

因为这个参数是作为最终方法的结果,所以很显然最终应该返回一个ArrayList,所以传参可以这么搞:

java8学习之Stream深度解析与源码实践第18张

接着再来传第二个参数,看下它的原型:

java8学习之Stream深度解析与源码实践第19张

那什么叫累加器呢?在方法注释上也可以看出:

java8学习之Stream深度解析与源码实践第20张

而BiConsumer的接口原型如下:

java8学习之Stream深度解析与源码实践第21张

那这个参数可以这样来传:

java8学习之Stream深度解析与源码实践第22张

还有最后一个参数,它也是BiFunction类型的,如下:

java8学习之Stream深度解析与源码实践第23张

这里先直接上代码,之后再来理解它:

java8学习之Stream深度解析与源码实践第24张

那对于第三个参数的合并器如何来理解呢?其实就是将上一次添的加结果集最终合并到要返回的结果集当中,其中theList1则为要返回的结果集,theList2为上一次累加的结果集,比较难以理解。

其实对于上面的实现还可以用方法引用的方式来代替,这里打算改用LinkedList再改用方法引用去弄,传第一个参数既要返回的结果:

java8学习之Stream深度解析与源码实践第25张

接着传第二个累加器参数,需要接收两个参数,无返回值,这时可以看一下LinkedList.add()方法,如下:

java8学习之Stream深度解析与源码实践第26张

所以第二个参数可以这样写:

java8学习之Stream深度解析与源码实践第27张

接着第三个参数,由于跟第二个参数类型一样,类似的对于LinkedList中有一个addAll方法:

java8学习之Stream深度解析与源码实践第28张

依然可以用方法引用嘛,如下:

java8学习之Stream深度解析与源码实践第29张

好了,接下来再回过头来继续读一下collect()方法:

java8学习之Stream深度解析与源码实践第30张

java8学习之Stream深度解析与源码实践第31张

接下来看一下参数的说明:

java8学习之Stream深度解析与源码实践第32张

java8学习之Stream深度解析与源码实践第33张

java8学习之Stream深度解析与源码实践第34张

再结合咱们的代码来说:

java8学习之Stream深度解析与源码实践第35张

接着再回到stream.collection(Collectors.toList())这个简单的重载方法,看一下它系统的实现:

java8学习之Stream深度解析与源码实践第36张

所以虽然复杂的这个重载方法理解起来比较麻烦,但是这个麻烦是值得滴,另外还有一个原因,因为stream.collection(Collectors.toList())只返回的是一个ArrayList,如果想要返回其它类型的集合如咱们已经实现的LinkedList,那就必须理解复杂的collect()。

免责声明:文章转载自《java8学习之Stream深度解析与源码实践》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇SSO单点登录一:cas单点登录防止登出退出后刷新后退ticket失效报500错,也有退出后直接重新登录报票根验证错误Kettle-Spoon入门示例下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

随便看看

嵌入式linux GUI--DirectFB + GTK至尊秘笈

我开始在x86上构建GTK环境。首先,我选择了最新版本。然后,我看到了GTK在帧缓冲区上以两种模式运行的介绍:DirectFB和linuxfb,而Linuxfb项目似乎已经停止。主要方向是DirectFB。后来,我找到了一个DirectFB+GTK的英文文档,它基本上使用了最新版本。许多软件包可以使用系统自己的,因此您可以编译必要的源代码。一开始,编译并不成...

db2 reorg详解

reorgchk,检查tableindex是否需要重组。reorg重组,重新放置数据位置。5)db.tb_reorg_req运行状况指示器处于ATTENTION状态。可以分为对系统表和用户表两部分分别进行REORGCHK:1)针对系统表进行REORGCHKdb2reorgchkupdatestatisticsontablesystem使用UPDATESTAT...

django的优缺点(非原创)

Django做了很多。使用它快速开发一些Web应用程序是很好的。因此,在一些人眼中,Django只不过是一种灵丹妙药,但对一些人来说,它也是一种毒药和剧毒。Django开发人员也讨论并试图支持SQLAlchemy,但最终放弃了。据估计,成本太高,很难与Django的其他模块集成。尽管Django的ORM不如SQLAlchemy强大,但它并不弱。Django的...

MIPS学习笔记(一)

本章涉及MIPS变量声明、数据输入和输出、地址获取、分支跳转语句,基本上对应于任何高级语言的最基本操作。该信息的确切形式因汇编程序而异。在MIPS程序集中,标签是后跟冒号的符号名称。)syscall程序的结尾与C类似,可以调用exit函数来停止程序的执行。停止MIPS程序的一种方法是使用类似于在C中调用exit的方法。MIPS中有一个移动指令,它将一个寄存器...

关于服务器并发量的简单计算

最简单的计算方式就是根据服务器带宽与页面的大小1.假设机房带宽为10Mbs,页面的大小为20KB同时并发量的理论值:10*1024/=64个请求/秒理论上1秒钟同时可以有64个请求访问页面。本考试系统,登陆的页面容量比较大,所有的js,css以及图片未优化前在400KB左右,我们就以400KB为基准,所有后面要用的文件是在首页一次性加载下来的。这一天的测评情...

GPU与CPU

GPU和CPU CPU,也称为中央处理单元,主要由控制器、运算单元、寄存器、高速缓冲区和数据/控制/状态总线组成。GPU GPU称为GraphicsProcessingUnit,即图形处理器。GPU最初是为终端游戏设计的。由于对游戏中的大量数据重复相同的操作,GPU面临着类型高度统一、相互依赖的大规模数据。GPU的内核远多于CPU。它向多个内核发送相同的指令...