Java8的Stream执行机制

Stream的概念解说

Stream的概念解说-Stream的含义

Stream:既是一个名称,也是一个动词
程序上的Stream是用来处理数据流,Java8新增的Stream API一般指用来处理有界数据流。
在这里插入图片描述

Stream的概念解说-现实类比

在这里插入图片描述

Stream的概念解说-Stream中的概念

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

Stream的执行机制

Stream的执行机制-最直接的流水线实现方式

在这里插入图片描述

Stream的执行机制-for循环也能干的事

显然,只要我们事先知道用户意图,采用下面方式实现跟Stream API等价的功能,既减少迭代次数,又避免不需要的中间结果存储
在这里插入图片描述

Stream API的设计者,如何无法事先知道用户意图的前提下实现流水线?

  • 细化各种操作,在构建流水线时把这些操作记录下来
  • 将操作叠加起来执行,减少迭代次数

假设我们有一个List包含一组整数,我们想要找出其中所有偶数并将它们加倍,然后计算总和。我们可以比较一下使用传统的for循环和使用Stream
API的方式来实现这个需求。

  • 传统的for循环实现方式:
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
int sum = 0;
for (int i = 0; i < numbers.size(); i++) {
    if (numbers.get(i) % 2 == 0) {
        sum += numbers.get(i) * 2;
    }
}
System.out.println(sum);
  • 使用Stream API实现方式
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
int sum = numbers.stream()
                 .filter(n -> n % 2 == 0)
                 .mapToInt(n -> n * 2)
                 .sum();
System.out.println(sum);

在这个例子中,我们使用传统的for循环对集合进行了两次迭代:一次用于筛选偶数,另一次用于计算总和。而使用Stream
API的方式中,所有操作都被合并在一次迭代中执行,只有在遇到sum终端操作时才会触发执行。因此,使用Stream
API的方式可以减少一次迭代,从而实现了操作次数少于传统for循环的效果。

Stream的执行机制-基本类图

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

Stream的执行机制-记录用户操作

在这里插入图片描述

Stream的执行机制-流转

流转1

在这里插入图片描述

流转2

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

流转3

操作的叠加,从流水线的head开始依次执行每一步的操作行不行?
首先,每个Stage既是PipelineHelper,又是Stream,前一个Stage不知道下一个Stage要做的操作
其次,每个操作的回调函数方式都不相同,只有Stage本身知道该如何执行自己包含的动作。
所以又引出了Sink的概念(使…下沉),Stream API通过Sink将两个Stage的执行承接起来,上游的元素处理完后,下沉到下游的处理逻辑。

在这里插入图片描述

流转4

在这里插入图片描述

Stream的执行机制-wrapAndCopyInto

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

Stream的执行机制-动画演示执行流程

20240304_213725

For循环与Stream性能对比

For循环与Stream的性能对比-基本类型

基本测试方案,初始化一个int数组,5亿个随机数。然后从数组中找到最小的一个数

在这里插入图片描述

针对基础类型(int)操作,结果分析:
1、串行Stream的执行的确不如for循环性能高,耗时大概是for循环的1.5~2倍。
2、并行Stream的执行性能要优于for循环,耗时大概是for循环的一半。

For循环与Stream的性能对比-对象类型

随机生成1千万个字符串List列表,通过不同的方式计算获得最小的字符串
在这里插入图片描述
针对对象(String)操作,结果分析:
1、Stream的性能与for循环已经相差不大了,耗时大概是for循环的1.25倍左右。
2、并行Stream执行的性能要优于for循环,而且比基础类型的优势更高,耗时已经低于for循环的一半

For循环与Stream的性能对比-复杂对象归约10个

List随机存放10个用户Order对象。计算每个用户的订单价格汇总
在这里插入图片描述
复杂对象千级归约操作,结果分析:
1、基于Stream的操作稍微比for循环的效率低,但是并行的效果更加明显。

For循环与Stream的性能对比-复杂对象归约百万

List随机存放百万个个用户Order对象。计算每个用户的订单价格汇总
在这里插入图片描述
复杂对象百万级归约操作,结果分析:
1、基于Stream的操作明显都高于for循环的效率,而且并行的效果更加明显。

For循环与Stream的性能对比-数据量级对性能的影响

JVM设置:-XX:+UseConcMarkSweepGC -Xms10G -Xmx10G
-XX:CompileThreshold=10000 分别用万级、十万级、百万级、千万级、亿级分别重复上述的三个实验,得到的结果分析:
在这里插入图片描述
原因分析
处理基础类型数据和对象类型 for 和stream 都需要加载数据到内存流(Stream)的特性是可以实现延迟加载和按需处理数据,以提高内存利用率和性能。所以复杂规约相对大数据量的时候会有性能优势。

  • 19
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

蜗牛乌龟一起走

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值