Stream的使用和原理分析

1 背景

Spliterator(splitable iterator可分割迭代器)接口是Java为了并行遍历数据源中的元素而设计的迭代器,这个可以类比最早Java提供的顺序遍历迭代器Iterator,但一个是顺序遍历,一个是并行遍历。
另外一个就是流式处理 ,通过函数式编程,按照顺序惰性式处理list的每一个元素。

2 基本逻辑原理

一个java 8的stream是由三部分组成的。数据源,零个或一个或多个中间操作,一个或零个终止操作。
中间操作是对数据的加工,注意,中间操作是lazy操作(惰性处理),并不会立马启动,需要等待终止操作才会执行。
终止操作:1)是stream的启动操作,只有加上终止操作,stream才会真正的开始执行,2)终止操作只能被执行一次。

3 惰性求值

在编程语言理论中,惰性求值(英语:Lazy Evaluation),又译为惰性计算、懒惰求值,也称为传需求调用(call-by-need),是一个计算机编程中的一个概念,它的目的是要最小化计算机要做的工作。它有两个相关而又有区别的含意,可以表示为“延迟求值”和“最小化求值”,

在jdk8的stream流编程里面,没有调用最终操作的时候,中间操作的方法都不会执行,这也是惰性求值。

4 操作类型

首先分为 中间操作 和 最终操作,在最终操作没有调用的情况下,所有的中级操作都不会执行。那么那些是中间操作那些是最终操作呢? 简单来说,返回stream流的就是中间操作,可以继续链式调用下去,不是返回stream的就是最终操作。这点很好理解。

最终操作里面分为短路操作和非短路操作,短路操作就是limit/findxxx/xxxMatch这种,就是找了符合条件的就终止,其他的就是非短路操作。在无限流里面需要调用短路操作,否则像炫迈口香糖一样根本停不下来!

中间操作又分为 有状态操作 和 无状态操作,怎么样区分呢? 一开始很多同学需要死记硬背,其实你主要掌握了状态这个关键字就不需要死记硬背。状态就是和其他数据有关系。我们可以看方法的参数,如果是一个参数的,就是无状态操作,因为只和自己有关,其他的就是有状态操作。如map/filter方法,只有一个参数就是自己,就是无状态操作;而distinct/sorted就是有状态操作,因为去重和排序都需要和其他数据比较,理解了这点,就不需要死记硬背了!

为什么要知道有状态和无状态操作呢?在多个操作的时候,我们需要把无状态操作写在一起,有状态操作放到最后,这样效率会更加高。

5 并行遍历Spliterators

下一次的起始是上一次的

6 实现原理初探

6.1 代码初步分析

1)数据源
2)Filter() /map()都是中间操作
3)Reduce是终止操作
在这里插入图片描述

6.2 求和的顺序

Item 就是一件商品 name是名字 qty是数量 price是价格
上图的需求就是从item集合里面 找出满足条件(qty大于等于30)的求总价

现在计算方式有两种:
1)先循环所有item 过滤后数量qty乘于价格得到item的总价
最后把所有item的总价加起来
2)从第一个item元素开始 如果满足条件 就数量qty乘于价格得到item的总价 然后循环第二item元素得到第二个的总价 然后调用Bigdecimal的add()加起来 直到循环到最后一个

Stream用的就是第二种
这种循环就是reduce()
一开始没有循环所有item的总价 都是在总价相加的时候计算 这种方式也就是惰性求值

下图的演示代码可以佐证
在这里插入图片描述

6.3 怎么设计代码按照求和顺序

7 源码分析

8 Stream idea调试

在这里插入图片描述
在这里插入图片描述

9 原理实现图小结

在这里插入图片描述
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值