由于本文需要有一定的Stream基础,所以如果不懂什么是Stream的同学请移步:Java---Stream入门

操作分类

graph LR
操作分类 --- 中间操作
终端操作 --- 操作分类
中间操作 --- 有状态
中间操作 --- 无状态
短路 --- 终端操作
非短路 --- 终端操作

中间操作只进行操作的记录,而实际的操作是由终端操作来执行的。如下面的例子。

张三的妈妈想让张三帮忙买调料,所以将需要购买的调料写在一张纸上交给张三。(中间操作)

纸:

小葱、大蒜、生姜、鸡精、酱油。。。

张三拿着纸条去买菜。(终端操作)

中间操作

中间操作分为两种:有状态,无状态。

  • 有状态:处理不止依赖当前元素。如,sorted(需要得到所有元素才可以排序不是吗)。
  • 无状态:处理只以来当前元素。如,map(只需要对当前元素进行类型转换不是吗)。

AbstractPipeline

非常重要的类,本质是个双链表,有着一下三个成员变量。Stream可以延迟执行的其中一个原因就是这个抽象类。可以说这个抽象类定义了中间操作的各种行为。

  • sourceStage:指向头结点。每一次中间操作会增加一个节点,为了在O(1)的时间复杂度找到头结点而定义。有点并查集的感觉。
  • previousStage:前驱节点。
  • nextStage:后驱节点。
  • sourceOrOpFlags:这里存的是一个int数值,来自枚举StreamOpFlag类。不用纠结这个类中各种数值的计算,这就是个标记,用来记录当前节点是做什么操作。如,filter等。

每一次中间操作就会生产一个上述节点。

终端操作

终端操作分为两种:短路与非短路

  • 短路:找到了满足条件的数据后直接中断操作。
  • 非短路:对于每个元素都做完一遍操作。

Sink

可以看出分为三种:Chained与Of,以及TerminalSink

  • Chained:用来生成中间操作的Sink链表。
  • Of:用来执行具体的accept。
  • TerminalSink:生成终端操作的Sink节点。

执行流程

样例

List<Integer> list = new ArrayList<>();
list.add(3);
list.add(1);
list.add(4);
list.add(2);
list.add(2);
list.stream().distinct().filter(t -> t < 4)
.map(String::valueOf).sorted()
.forEach(System.out::println);

可以看出Stream的执行流程如下:

逐步生成每一步中间操作的节点 -> 生成终端操作的Sink节点 -> 生成每一步中间操作的Sink节点 -> begin -> 执行各个中间操作以及终端操作 -> end

简单阐述下Stream流程的三个部分:

  1. 获取head且逐步生成AbstractPipeline的双链表。
  2. 从上述双链表的最后一个节点向前驱节点迭代生成Sink链表。
  3. 迭代Sink链表逐个执行中间操作与终端操作。

并行流的执行使用了ForkJoin架构,先根据元素的数量通过分治的方式分解为单一元素的Stream,对单个Stream处理,然后再合并。

流程也符合上述案例,但各个部分的执行实际上存在并发并行,多了最后的合并操作。

本文建议结合源码一起阅读理解,涉及到的源码特别多(建议适当阅读,碰到复杂难懂的算法可以跳过,不要死磕),所以本文中并未贴出。

Java---Stream进阶的更多相关文章

  1. java stream collector

    Java Stream API进阶篇 本文github地址 上一节介绍了部分Stream常见接口方法,理解起来并不困难,但Stream的用法不止于此,本节我们将仍然以Stream为例,介绍流的规约操作 ...

  2. Java基础进阶

    Java基础进阶J Object类 hashcode() toString() clone() getClass() notify() wait() equals() Random类 生成 随机数 U ...

  3. 全面吃透JAVA Stream流操作,让代码更加的优雅

    全面吃透JAVA Stream流操作,让代码更加的优雅 在JAVA中,涉及到对数组.Collection等集合类中的元素进行操作的时候,通常会通过循环的方式进行逐个处理,或者使用Stream的方式进行 ...

  4. 3.Java异常进阶

    3.JAVA异常进阶 1.Run函数中抛出的异常 1.run函数不会抛出异常 2.run函数的异常会交给UncaughtExceptionhandler处理 3.默认的UncaughtExceptio ...

  5. Java Stream 使用详解

    Stream是 Java 8新增加的类,用来补充集合类. Stream代表数据流,流中的数据元素的数量可能是有限的,也可能是无限的. Stream和其它集合类的区别在于:其它集合类主要关注与有限数量的 ...

  6. Java Stream API性能测试

    已经对Stream API的用法鼓吹够多了,用起简洁直观,但性能到底怎么样呢?会不会有很高的性能损失?本节我们对Stream API的性能一探究竟. 为保证测试结果真实可信,我们将JVM运行在-ser ...

  7. Java字符串进阶

    Java字符串进阶 前言 最常用的对字符串操作的类有三个,分别是String,StringBuilder,StringBuffer,下面将会详细的说说这三个类...... String String类 ...

  8. java stream 原理

    java stream 原理 需求 从"Apple" "Bug" "ABC" "Dog"中选出以A开头的名字,然后从中选 ...

  9. 总结:Java 集合进阶精讲2-ArrayList

    知识点:Java 集合框架图 总结:Java 集合进阶精讲1 总结:Java 集合进阶精讲2-ArrayList 初探: ArrayList底层结构是数组,是List接口的 可变数组的实现,所以会占用 ...

  10. 总结:Java 集合进阶精讲1

    知识点:Java 集合框架图 总结:Java 集合进阶精讲1 总结:Java 集合进阶精讲2-ArrayList 集合进阶1---为集合指定初始容量 集合在Java编程中使用非常广泛,当容器的量变得非 ...

随机推荐

  1. Redis开机自启

    添加开机启动服务 vi /etc/systemd/system/redis.service 在redis.service中输入以下内容 ps:ExecStart配置成自己的路径 [Unit] Desc ...

  2. Java开发学习(八)----IOC/DI配置管理第三方bean、加载properties文件

    前面的博客都是基于我们自己写的类,现在如果有需求让我们去管理第三方jar包中的类,该如何管理? 一.案例:数据源对象管理 本次案例将使用数据源Druid和C3P0来配置学习下. 1.1 环境准备 学习 ...

  3. 【UR #2】猪猪侠再战括号序列 题解

    题目链接 前言 是的没脑子选手只会做签到题. 思路分析 一开始把题目看成反转括号的状态,直接浪费 \(40\ mins\) . 我们考虑把不确定的"正确括号"转换成一个固定的括号序 ...

  4. HashSet存储自定义类型元素和LinkedHashSet集合

    HashSet集合存储自定义类型元素 HashSet存储自定义类型元素 set集合报错元素唯一: ~存储的元素(String,Integer,-Student,Person-)必须重写hashCode ...

  5. JUC源码学习笔记1——AQS和ReentrantLock

    笔记主要参考<Java并发编程的艺术>并且基于JDK1.8的源码进行的刨析,此篇只分析独占模式,后续在ReentrantReadWriteLock和 CountDownLatch中 会重点 ...

  6. java--方法/debug

    一.方法的定义 1.什么是方法 方法是将具体独立功能的代码块组织称为一个整体,使其具有特殊功能的代码集 注意: 方法必须先创建后使用,该过程为方法定义: 方法创建后并不是直接运行的,需要手动十一后执行 ...

  7. java 九九乘法表(for循环)

    package study5ran2yl.study; public class ForDemo01 { public static void main(String[] args) { int h; ...

  8. 零基础学Java(6)控制流程

    控制流程 与任何程序设计语言一样,Java使用条件语句和循环结构确定控制流程. 块作用域 我们首先要了解块(block)的概念. 块是指由若干条Java语句组成的语句,并用一对大括号括起来.块确定了变 ...

  9. 在 SQL Server 中查找活动的 SQL 连接

    在SQL Server中有几种方法可以找到活动的 SQL 连接.让我们看看一些使用 T-SQL 查询的简单快捷的方法. SP_WHO SP_WHO 是 SQL Server 内置的系统存储过程, 其他 ...

  10. dos命令-*02

    1.cmd状态下 tab快速补充文件名 ↑↓快速填充之前输入的文件名 2.//这是Java的快速入门 //对代码的相关说明 //1.public class Hello 表示Hello是一个类,是一个 ...