JavaStream数据处理的两大特点:延迟执行与不可变

最近在公司写业务的时候,忽然想不起来Stream中的累加应该怎么写?

无奈只能面向谷歌编程,花费了我宝贵的三分钟之后,学会了,很简单。

自从我用上JDK8以后,Stream就是我最常用的特性,各种流式操作用的飞起,然而这次事以后我忽然觉得Stream对我真的很陌生。

可能大家都一样,对最常用到的东西,也最容易将其忽略,哪怕你要准备面试估计也肯定想不起来要看一下Stream这种东西。

不过我既然注意到了,就要重新梳理一遍它,也算是对我的整体知识体系的查漏补缺。

花了很多功夫来写这篇Stream,希望大家和我一块重新认识并学习一下Stream,了解API也好,了解内部特性也罢,怕什么真理无穷,进一步有进一步的欢喜。

在本文中我将Stream的内容分为以下几个部分:

初看这个导图大家可能对转换流操作和终结流操作这两个名词有点蒙,其实这是我将Stream中的所有API分成两类,每一类起了一个对应的名字(参考自Java8相关书籍,见文末):

  • 转换流操作 :例如filter和map方法,将一个Stream转换成另一个Stream,返回值都是Stream。

  • 终结流操作 :例如count和collect方法,将一个Stream汇总为我们需要的结果,返回值都不是Stream。

其中转换流操作的API我也分了两类,文中会有详细例子说明,这里先看一下定义,有一个大概印象:

  1. 无状态 :即此方法的执行无需依赖前面方法执行的结果集。

  2. 有状态 :即此方法的执行需要依赖前面方法执行的结果集。

由于Stream内容过多,所以我将Stream拆成了上下两篇,本篇是第一篇,内容翔实,用例简单且丰富。

第二篇的主题虽然只有一个终结操作,但是终结操作API比较复杂,所以内容也翔实,用例也简单且丰富,从篇幅上来看两者差不多,敬请期待。


:由于我本机的电脑是JDK11,而且写的时候忘了切换到JDK8,所以在用例中大量出现的List.of()在JDK8是没有的,它等同于JDK8中的Arrays.asList()

:写作过程中翻读了大量Stream源码和Java8书籍(文末),创作不易,点赞过百,马上出第二篇。

1. 为什么要使用Stream?

一切还要源于JDK8的发布,在那个函数式编程语言如火如荼的时代,Java由于它的臃肿而饱受诟病(强面向对象),社区迫切需要Java能加入函数式语言特点改善这种情况,终于在2014年Java发布了JDK8。

在JDK8中,我认为最大的新特性就是加入了函数式接口和lambda表达式,这两个特性取自函数式编程。

这两个特点的加入使Java变得更加简单与优雅,用函数式对抗函数式,巩固Java老大哥的地位,简直是师夷长技以制夷。

而Stream,就是JDK8又依托于上面的两个特性为集合类库做的 一个类库,它能让我们通过lambda表达式更简明扼要的以流水线的方式去处理集合内的数据,可以很轻松的完成诸如:过滤、分组、收集、归约这类操作,所以我愿将Stream称为函数式接口的最佳实践。

1.1 更清晰的代码结构

Stream拥有更清晰的代码结构,为了更好的讲解Stream怎么就让代码变清晰了,这里假设我们有一个非常简单的需求:在一个集合中找到所有大于2的元素

先来看看没使用Stream之前:

        List<Integer> list = List.of(1, 2, 3);
        
        List<Integer> filterList = new ArrayList<>();
        
        for (Integer i : list) {
            if (i > 2) {
                filterList.add(i);
            }
        }
        
        System.out.println(filterList);
复制代码

上面的代码很好理解,我就不过多解释了,其实也还好了,因为我们的需求比较简单,如果需求再多点呢?

每多一个要求,那么if里面就又要加一个条件了,而我们开发中往往对象上都有很多字段,那么条件可能有四五个,最后可能会变成这样:

        List<Integer> list = List.of(1, 2, 3);

        List<Integer> filterList = new ArrayList<>();

        for (Integer i : list) {
            if (i > 2 && i < 10 && (i % 2 == 0)) {
                filterList.add(i);
            }
        }

        System.out.println(filterList);
复制代码

if里面塞了很多条件,看起来就变得乱糟糟了,其实这也还好,最要命的是项目中往往有很多类似的需求,它们之间的区别只是某个条件不一样,那么你就需要复制一大坨代码,改吧改吧就上线了,这就导致代码里有大量重复的代码。

如果你Stream,一切都会变得清晰易懂:

        List<Integer> list = List.of(1, 2, 3).stream()
                .filter(i -> i > 2)
                .filter(i -> i < 10)
                .filt
  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值