当前位置:首页 > 每日看点

如何理解ja8中stream的延迟作的意思?

卡卷网2年前 (2025-01-10)每日看点322

你贴出来的解释已经很清晰了:

    只有当一个<>终端作被调用时,例如forEach()collect()reduce()等,Stream管道(pipeline)才会被<>启动<>只遍历一次数据源完成所有指定的作

这里不直接解释什么是延迟作(LazyEvaluation),咱们边写边聊。

<>最终的目的:写出一个大致符合上面<>两点要求的SimpleStream(仿Ja8StreamAPI)

手写Stream版本1

在filter执行时,打印:element+_filter

很简单,应该都能看懂。然后给上面的Stream写一个:

故意把filter和forEach拆成两段代码

在终端作forEach执行前,调用filter时已经开始处理元素了,不符合文章最开始定义的第一条:终端作调用时才启动。

手写Stream版本2

版本2版本1更好理解,而且效果也更好。同样的案例,得到的结果是:

版本2符合第一点定义(其实也符合第二点定义)。

手写Stream版本3

如果再来一个map(),难道要这样?

再来一个peek()呢?再定一个变量保存peek作?很显然,<>为每一种作定义一个变量来存储的做法是不可行的。

代码迭代到这,从面向对象的角度,一般会倾向于抽象。同为中间作,filter看起来和map有很大的不同,如果把peek也算进来,可的算是一锅乱炖:

    filter:接受一个item,返回ooleanmap:接受一个item,返回另一个类型的itempeek:接受一个item,做一些作,不返回

返回值完全不同,甚至有些作没有返回值,似乎不好做函数抽象。但是换个角度,这些中间作就像一节节下水管道,水至上而下流过,只有两种可能:

    流不下来(蒸发了)流下来了(不管发生了什么化学反应,变成了什么)

所以,这里打算抽象出一个Stage。

privateinteceStage{ Ojectaccept(Ojectitem); }

为了简单起见,就不整泛型了,看着烦。

FilterStage和MapStage长啥样呢?

很简单对吧,Stage也没什么大不了的,<>就是把predicate和mapper包一下,不管内地的、的、的,纵然有这样或那样的不同,都是中国人对吧。用一个更大的抽象概念,去求同存异即可。

既然都是Stage,自然就可以用List<Stage>去<>一存储所有中间作。

重点看forEach:遍历每一个元素,为每个元素先执行中间作、再执行终端作,如果没有终端作,中间作不会启动(只是被存起来而已)。

至此,开头定义的第一、第二点都符合了。再来一把:

李健被filter了,所以没有后续作。元素也确实是逐个执行,并且仅遍历一次。

手写Stream版本4

为了稍微接近Ja8的StreamAPI,这里再迭代:优化forEach中的process。

process的逻辑是,对当前遍历到的元素,逐个执行所有中间作,内部用的是for循环。现在我要把它改成一种类似<>链式结构,你也可以叫它责任链,anyway。

怎么引入链式结构呢?这取决于你期望借助链式结构达到什么效果。

如,我期望最终的写法是这样的:

先别管Sink是什么,你可以把它看作另一种Stage,也是对中间作的封装。总之,通过wrapStages(),我们得到了一种链式结构,这条链上有我们通过filter()、map()等方法压入的中间作,<>只要调用sink.accept(element),element就会沿着链条执行下去,就像往下水道倒了一碗水。

开始实施。

目前:stage负责<>封装中间作

目标

    stage:组装链式结构sink:<>封装中间作、当前作执行结束后,<>将流程推向下一个

发现了吗,原本stage的职责转移给了sink,它有了新的职责:组装链式结构。

链式结构怎么来的

filter()、map()这些方法只负责存储predicate等作、不涉及组装,等到forEach触发后才会调用wrapStages()组装链式结构。

第10行:stage.wrap(sink)是核心逻辑

以filterStage为例:

newNode=wrap(oldNode)

也就是说,wrap干了两件事:

    创建并返回新节点通过闭包,在新节点内部维持对旧节点的引用
      forEachfilter->forEachmap->filter->forEach

链式作如何执行

调用forEach开启管道作:

pulicvoidforEach(Consumer<?superT>action){ Sinksink=wrapStages(newForEachSink<>(action)); for(Telement:soce){ //上面组装成功后,开始遍历元素:把元素倒入下水道 sink.accept(element); } }

accept是管道作的入口,从filter开始:

代码已上传到git仓库:com/ro/advanced/fluent/stream2

ro1988/design-pattern

对设计模式、Ja进阶感兴趣,可以参考以下路线。

ro1988:Ja程序员练级路线

扫描二维码推送至手机访问。

版权声明:本文由卡卷网发布,如需转载请注明出处。

本文链接:https://www.kajuan.net/ttnews/2025/01/8449.html

分享给朋友:

相关文章

k70和红米note14pro+咋选啊?

k70和红米note14pro+咋选啊?

首选红米K70,可满足题主的功能需求。 红米 Note 14 pro+的使用者定位并不是学生,红米K70的使用者定位才是学生。 一、k70和红米note14pro+各自的参数 红米K70推出的定位初衷,是主打性能为主。最佳使用对象是喜欢…

Photoshop 有哪些使用技巧?

Photoshop 有哪些使用技巧?

不看后悔系列!本篇分享25个PS实用的技巧! 不能保证每个都能让你惊艳,但是却是我用心写出来的,希望对你有帮助。 另外我的知乎也写了接近200篇PS的技巧,超级合集分享! 分享25个关于PS的技巧 一、快速制作文字倒影1、新建文档,15…

你每天用来涨知识的手机应用程序有哪些?

你每天用来涨知识的手机应用程序有哪些?

经过深度使用和测评, 从100个APP中选出的这35个超实用的app,每一个都是最硬核最有料的涨知识神器!每天打开看看,能让你提神醒脑,眼界大开,成为朋友聚会上的话题王者! 先放上全部APP目录,有新闻资讯类、英语学习类、读书类、影视类…

拼多多,怎么就成为了年轻人的「赛博菜市场」?

拼多多,怎么就成为了年轻人的「赛博菜市场」?

可惜你不在拼多多买水果蔬菜,很难一句话跟你解释,我只能笨拙的用经历来慢慢讲。 我们公司有微波炉,同事们几乎都是自己带饭来上班,便当荤素搭配、水果零食;都是好看又好吃。 我自己本来就不喜欢外卖,当然也加入了带饭大军: 直到某一天深夜我闲着…

为什么有人觉得华为mate60只值2000?

为什么有人觉得华为mate60只值2000?

你以为买Mate60的人真的傻?真的那么爱国? 国庆前,我家那傻子加价800多买了一台Mate60,当时还被我骂他是傻子。 可是他说一回到公司就被老板同事朋友看到,拿去反复查看,都在惊叹他这么快就买到新机。 跟亲戚朋友聚会,别人一看就知道他…

有没有高手指点一下Google做SEO现在的技巧啊?心好累。

有没有高手指点一下Google做SEO现在的技巧啊?心好累。

搜索引擎优化 (SEO) 的目标是让 Google 在用户输入相关搜索查询时提供您的网页链接。 虽然没有固定的蓝图可以保证您获得最高排名,但有几种 SEO 最佳实践(您可以将其视为 SEO 规则)可以增加您在非付费结果中获得良好排名的机会。…

发表评论

访客

看不清,换一张

◎欢迎参与讨论,请在这里发表您的看法和观点。