美文网首页
Java8 Stream API的一点理解

Java8 Stream API的一点理解

作者: Yellowtail | 来源:发表于2019-11-08 11:54 被阅读0次

概述

使用了 Java8Stream API 之后,在这里写下自己的理解,督促自己,也分享给大家

打印问题

看下代码, 问:

  1. 代码能编译通过吗?
  2. 如果可以编译通过,执行一下代码,在 done 之前会输出什么东西?
public static void main(String[] args) {
    
    List<String> list = Arrays.asList("123", "abc", "123", "456");
    
    list.stream()
        .filter("123"::equals)
        .filter(k -> {
            System.out.println(k);
            return true;
        });
    
    System.out.println("done");
}

自问自答

我来分别回答一下上面提的问题

问题1, 代码能编译通过吗?
回答是: 可以,filter 写完对象其实是一个 Stream<String> 对象

问题2, 在 done 之前输出什么?
回答是: 什么都不会输出
有的同学可能会回答是,输出了两个 123
这么理解是不对的,第二个 filter 里面的代码至始至终都没有被运行过

要理解这个问题,看下我的分析和理解

Stream

如果把 Stream 比喻为 洗手间的感应式水龙头管道, 这样大家可能比较好理解

看图


stream

我们在 stream 后面,
filter 的时候,相当于在给管道加过滤网, 只有符合条件的水,才能继续往下流
map 的时候,相当于再给管道加转换器, 如把冷水加热变为 热水自来水 净化成 可饮用水

那么思考一下问题2
为什么不会输出?

因为 Stream 有个特性就是 惰性求值
也可以理解为 没有终止操作的时候,流的中间过程是不会执行的
即: 没有订阅者的时候,流不会执行
即: 水龙头下面没有手的时候,水龙头是不会出水的

惰性求值

惰性求值,在Stream的很多地方都体现出来了
比如 Spring 5Flux or Mono 不添加订阅者(或者称之为消费者)的时候,代码不会真正的去运行
Java 9 里的 Flow 亦是如此

循环次数

我们把代码改一改,增加一个什么都不做的消费者

public static void main(String[] args) {
        
    List<String> list = Arrays.asList("123", "abc", "123", "456");
    
    list.stream()
        .filter("123"::equals)
        .filter(k -> {
            System.out.println(k);
            return true;
        })
        .forEach(k -> {});
        ;
    
    System.out.println("done");
}

再提出一个问题:对于代码里的 第二个filter,它收到的数据是什么样的?
或者换个说法,我们知道第二个filter 处理的数据是 [123 123]
但是这两个数据是一起过来的,还是分批来的?

借用上面的例子 洗手间的感应式水龙头管道
假设把水分为5份,那么逻辑是不是这样的:
第一个filter拿到5份水之后,遍历,过滤,剩下两份水,
第二个filter拿到两份水,遍历,过滤,剩下两份水(因为return true

还是说是别的场景?

其实流程不是这样的,看源码得知:
水分为5份,编号为 水1、水2。。。水5
水1 先尝试流经 Stream的这整个管道(如果能通过的话)
接着是水2
最后是水5

结论是: 至始至终,只循环了一次

相关文章

  • Java8新特性——强大的Stream

    Stream API 了解Stream Java8中有两个比较大的改变 Lambda表达式 Stream API ...

  • JAVA8中Stream学习

    JAVA8中Stream学习 最近看了下Stream的api: Stream用户操作Collection族的数据,...

  • Stream

    使用 Stream API 高逼格 优化 Java 代码 Java8 Stream流中的 collect() 别再...

  • Java8 stream API以及常用方法

    Java8引入了全新的Stream API,Stream API为Java编程提供了丰富的函数式编程操作。Stre...

  • Java8 Stream-API

    Java8 Stream-API Stream 流类似集合类中的Iterator,但是比Iterator高级,只需...

  • Java 8 Stream 教程

    本文采用实例驱动的方式,对JAVA8的stream API进行一个深入的介绍。虽然JAVA8中的stream AP...

  • Java8 Stream API的一点理解

    概述 使用了 Java8 的 Stream API 之后,在这里写下自己的理解,督促自己,也分享给大家 打印问题 ...

  • Java8 Stream API 笔记

    Java8 Stream API 笔记 常用的stream操作,做个记录,方便日后使用查询。 [TOC] 1. f...

  • java中List去重

    方法一、使用Set集合特性 方法二、使用java8 stream api

  • 03_Java8_Lamda表达式学习

    Java8 的新特性:Lambda表达式、强大的 Stream API、全新时间日期 API、Concurrent...

网友评论

      本文标题:Java8 Stream API的一点理解

      本文链接:https://www.haomeiwen.com/subject/njuibctx.html