Java—Stream进阶

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

操作分类

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

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

张三的妈妈想让张三帮忙买调料,所以将需要购买的调料写在一张纸上交给张三。(中间操作)
纸:
小葱、大蒜、生姜、鸡精、酱油。。。
张三拿着纸条去买菜。(终端操作)

中间操作

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

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

Java---Stream进阶

AbstractPipeline

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

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

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

终端操作

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

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

Java---Stream进阶

Sink

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

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

执行流程

样例

List 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);

Java---Stream进阶

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

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

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

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

并行流的执行使用了ForkJoin架构,先根据元素的数量通过分治的方式分解为单一元素的Stream,对单个Stream处理,然后再合并。
流程也符合上述案例,但各个部分的执行实际上存在并发并行,多了最后的合并操作。

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

Original: https://www.cnblogs.com/buzuweiqi/p/16625009.html
Author: buzuweiqi
Title: Java—Stream进阶

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/584786/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • 代码审查:从 ArrayList 说线程安全

    本文从代码审查过程中发现的一个 ArrayList 相关的「线程安全」问题出发,来剖析和理解线程安全。 案例分析 前两天在代码 Review 的过程中,看到有小伙伴用了类似以下的写…

    Java 2023年6月5日
    094
  • 【Spring学习】AOP实现日志记录

    AOP知识点 AOP,面向切面编程。通过预编译方式和运行时动态代理实现在不修改源代码的情况下给程序动态统一添加功能的一种技术。 AOP编程思想就是把很多类对象中的横切问题点,从业务…

    Java 2023年6月5日
    095
  • Css3入门详解

    一、Css基本语法 1.Html和Css没分开 点击查看代码 <!DOCTYPE html> <html lang="en"> <…

    Java 2023年6月13日
    064
  • nginx单页应用配置

    location ~* html { rewrite .* /index.html break; } location /login { rewrite .* /index.htm…

    Java 2023年5月30日
    060
  • 【Swift 4.2】uuid 取 hashCode(与 Java/Go/Kotlin 一致)

    Swift 获取 uuid 字符串的 hashCode,参考 Go 的代码改的,需要的拿走 extension String { func hashCode() -> Int…

    Java 2023年5月29日
    060
  • MySQL学习之路(1):SQL脚本语言

    使用MySQL数据库,首先安装MySQL数据库,本文所有SQL脚本在MySQL上测试和执行。 安装Mysql服务器;安装Mysql workbench客户端,可以以图形化界面管理m…

    Java 2023年6月6日
    044
  • 解决 Docker Push Skipped foreign layer 的错误

    引言当Docker推送基于Windows镜像到私有仓库的时候会遇到 Skipped foreign layer的问题。 docker push 192.168.2.30:5000/…

    Java 2023年6月15日
    056
  • Takeown、Cacls、Icacls-文件、文件夹夺权用法

    本文补充下常用的文件、文件夹夺权或者夺取所有者的方法,涉及Takeown、Cacls、Icacls用法。 takeown /f 文件名 获取该文件的所属权 takeown /f /…

    Java 2023年5月30日
    075
  • nginx 屏蔽ip

    在网站运行过程中,我们有的时候需要对某个IP或者IP段进行封禁,禁止IP访问本服务器,如果服务器的环境用的是Nginx,下面我们来看看Nginx如何禁止某个IP访问! 方法一:首先…

    Java 2023年5月30日
    077
  • kafka-connect-kudu-sink插件

    kafka-connect-hive是基于 kafka-connect平台实现的 hive数据读取和写入插件,主要由 source、 sink两部分组成, source部分完成 h…

    Java 2023年6月6日
    082
  • 事务的隔离级别详解

    四种隔离级别: READ-UNCOMMITTED(读取未提交): 最低的隔离级别,允许读取尚未提交的数据变更, 可能会导致脏读、幻读或不可重复读 。 READ-COMMITTED(…

    Java 2023年6月5日
    082
  • Mybatis中jdbcType和javaType的对应关系

    JDBC Type Java Type 2 CHAR String 3 VARCHAR String 4 LONGVARCHAR String 5 NUMERIC java.mat…

    Java 2023年5月29日
    0113
  • Cannot deserialize instance of `java.lang.String` out of START_OBJECT token

    前端请求进入后端控制器报错【Cannot deserialize instance of java.lang.String out of START_OBJECT token】,从…

    Java 2023年5月29日
    081
  • java中线程的几种实现方式

    继承Thread类来实现 由于在java中采用单继承的模式,因此继承Thread类有一个明显的缺点就是占用了唯一的extends,是的我们无法在继承其它的类,因此一般不会采用这种方…

    Java 2023年6月6日
    080
  • java多线程回顾4:线程通信

    1 、线程的协调运行 线程的协调运行有一个经典案例,即生产者和消费者问题。 假设有一个货架,生产者往货架上放货物,消费者从货架上取货物。 为了方便讲解,制定一个规则,生产者每放上一…

    Java 2023年6月15日
    081
  • jdk9下载

    https://www.oracle.com/java/technologies/javase/javase9-archive-downloads.html Original: h…

    Java 2023年5月30日
    059
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球