java零基础教学篇之Stream流

817 阅读7分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第29天,点击查看活动详情

👨‍🎓作者:bug菌

✏️博客:CSDN掘金

💌公众号:猿圈奇妙屋

🚫特别声明:原创不易,转载请附上原文出处链接和本文声明,谢谢配合。

🙏版权声明:文章里可能部分文字或者图片来源于互联网或者百度百科,如有侵权请联系bug菌处理。

一、前言🔥

       哈喽,小伙伴们,我是bug菌呀👀,不知不觉就一年又4月,正是踏青郊游的好时节。可上海疫情,除了在家远程办公就是看点技术顺便卷点文章。这不是4月又出了更文活动,逼自己一把,坚持每天做点内容输出,养成写作习惯,将来你会回来感谢曾经的自己坚持了一把才有此刻的辉煌成就。

       小伙伴们在批阅文章的过程中如果觉得文章对您有一丝丝帮助,还请别吝啬您手里的赞呀,大胆的把文章点亮👍吧,您的点赞三连(收藏⭐️+关注👨‍🎓+留言📃)就是对bug菌我创作道路上最好的鼓励与支持😘。时光不弃🏃🏻‍♀️,掘金不停💕,加油☘️​

二、版本说明🔥

环境:springboot2.3.1.RELEASE + jdk1.8

三、正文🔥

      谈到Stream,你们第一眼想到了啥?I/O Stream?其实我在接触它之前看到第一眼也以为是io流那一块的东西,不是的哈。没有谁规定io就一定是io流,在java8中,由于Lambda的诞生与崛起,链式编程跑上热潮,从而也引入了一个对Stream的新概念,主要作用于解决当前集合类库的一些弊端。

1️⃣引言

       传统集合中,可以说几乎所有的集合(Collection 或 Map等)都支持直接或间接的遍历操作。而我们对集合的操作除了必要的插入、删除、获取外,操作最多就是对集合进行遍历了。那么你有没有想过,循环遍历是否有啥弊端?

       首先问大家个问题,为什么要使用循环?因为要遍历。但循环是遍历的唯一操作方式吗?遍历是对每一个元素逐一进行处理,而并不是从第一个到最后一个顺序处理的循环。总而言之就是前者是目的,而后者是方式。

       再问大家一个问题,如果对集合中的元素进行有条件的筛选,你们打算怎么做?

       我具体给大家设计个场景,比如一个集合stus中存储了全班同学的姓名,现在要求你把姓罗且两个字名称的同学名单筛选出来,可能在java8之前,大部分人可能会这么干!

2️⃣传统for循环法

具体演示代码如下:

    @Test
    public void test() {

        //存放全班同学姓名集合
        List<String> stus = new ArrayList<>();
        stus.add("罗志祥");
        stus.add("罗成");
        stus.add("黄忠");
        stus.add("马超");
        stus.add("后羿");

        //存储指定数据集合
        List<String> luoList = new ArrayList<>();
        for (String name : stus) {
            if (name.length() == 2 && name.startsWith("罗")) {
                luoList.add(name);
            }
        }

        //打印姓罗且名字两个字的同学姓名
        for (String name : luoList) {
            System.out.print(name + " ");
        }
    }

代码运行截图:

       很明显输出答案就唯有【罗成】符合题目要求,对吧。那看完上述这段代码,我们再来解析一下,它共有3个循环,分别解释如下:

  1. 循环1负责存放全班同学姓名。
  2. 循环2负责筛选出含有符合题意的姓名。
  3. 循环3打印出符合符合题意的姓名。

       当我们需要对集合进行操作时,对集合进行遍历是避免不了的,而且一次还可能不够,循环再循环...那么是否有更优雅的实现方式呢?那么就用到今天我给大家提到的java8新特性之一Stream流。

3️⃣Stream流写法

       下面请大家看看,我是如何借助java8的Stream API来实现上述需求的,什么才叫简洁优雅。

具体演示代码如下:

    @Test
    public void test1() {

        //存放全班同学姓名集合
        List<String> stus = new ArrayList<>();
        stus.add("罗志祥");
        stus.add("罗成");
        stus.add("黄忠");
        stus.add("马超");
        stus.add("后羿");

        //筛选+输出打印一步到位
        stus.stream()
                .filter(s -> s.startsWith("罗"))
                .filter(s -> s.length() == 2)
                .forEach(System.out::print);
    }

代码运行截图:

       仔细阅读代码,从获取流、过滤姓、过滤姓名长度、逐一打印。代码全程中并没有体现使用线性循环或者其他任何算法进行遍历,而我们真正要做的事内容被更好的在代码中进行体现。怎么样,感受到了Stream流的优雅了么,写法那是非常的简洁啊,绝绝子。

4️⃣流式思想概述

       整体来看,流就类似工厂车间的“流水线”,当我们要对一个集合进行多步操作时,考虑到性能及整体便捷性,我们首要应该是拼好一个“流水线”模型,一步一步执行下去,比如:

       如上这张图中展示了Stream流中的过滤、映射、跳过、计数多步操作后得出答案,这是对集合的一种处理方案,反过来看,方案就是“流水线”模型。

       上图中每个框都是一个“流”,调用专门的方法,可以从一个流模型转换为另一个“流”模型。最终的3就是答案。

**注意:Stream流就是一个集合元素的函数模型,它不是集合,也不是数据结构,其本身并不存储任何元素,**请大家不要误解了。

       Stream流是一个来自数据源的元素队列。其中数据源可以是一个集合或者数组等。和以前的Collection集合操作不同,Stream流它还有两个基础特征,具体如下:

  • Pipelining: 中间操作都会返回流对象本身。 这样多个操作可以串联成一个管道, 如同流式风格(fluentstyle)。 这样做可以对操作进行优化, 比如延迟执行(laziness)和短路( short-circuiting)。
  • 内部迭代: 以前对集合遍历都是通过Iterator或者增强for的方式来处理, 显示的在集合外部进行迭代, 这叫做外部迭代。 Stream提供了内部迭代的方式,流可以直接调用遍历方法。

       当使用一个流的时候,通常包括三个基本步骤:获取一个数据源(source)—> 数据转换—>执行操作获取想要的结果,每次转换原有 Stream 对象不改变,返回一个新的 Stream 对象(可以有多次转换),这就允许对其操作可以像链条一样排列,变成一个管道。

... ...

       ok,以上这样就好啦,如果还想学习更多,你可以看看我的往期热文推荐哦,每天积累一个奇淫小知识,日积月累下去,你一定能成为令人敬仰的大佬的。好啦,咱们下期见~

四、往期推荐🔥

五、文末🔥

       如果还想要学习更多,小伙伴们可关注bug菌专门为大家创建的专栏《SpringBoot零基础入 门》,从无到有,从零到一!希望能帮到大家。

       我是bug菌,一名想走👣出大山改变命运的程序猿。接下来的路还很长,都等待着我们去突破、去挑战。来吧,小伙伴们,我们一起加油!未来皆可期,fighting!

最后送大家两句我很喜欢的话,与诸君共勉!

**************************************************

☘️做你想做的人,没有时间限制,只要愿意,什么时候都可以start,

🍀你能从现在开始改变,也可以一成不变,这件事,没有规矩可言,你可以活出最精彩的自己。

**************************************************

💌如果文章对您有所帮助,就请留下您的吧!(#^.^#);

💝如果喜欢bug菌分享的文章,就请给bug菌点个关注吧!(๑′ᴗ‵๑)づ╭❤~;

💗如果对文章有任何疑问,还请文末留言或者加群吧【QQ交流群:708072830】;

💞鉴于个人经验有限,所有观点及技术研点,如有异议,请直接回复参与讨论(请勿发表攻击言论,谢谢);

💕版权声明:原创不易,转载请附上原文出处链接和本文声明,版权所有,盗版必究!!!谢谢。