Stream是什么?
Stream是一个高级迭代器,它不是数据结构,不能存储数据。它可以用来实现内部迭代,内部迭代相比平常的外部迭代,它可以实现并行求值(高效,外部迭代要自己定义线程池实现多线程来实现高效处理)、惰性求值(中没有终止操作,中间操作是不会执行的)、短路操作(拿到正确的结果就返回,不需要等到整个过程完成之后)等
-
Stream翻译过来的意思就是“溪流,流”的意思,而我们刚开始学习java的时候接触最多的就是IO流,它更像“农夫山泉”,“我们只做大自然的搬运工”,只是将一个文件从这个地方传到另一个地方,对于文件当中内容不做任何增删改操作,而Stream就会,也就是将要处理的数据当作流,在管道中进行传输,并在管道中的每个节点对数据进行处理,如过滤、排序、转换等;
-
通常我们需要处理的数据是以 Collection 、Array等数据来源;
-
Stream它是Java8中的一个新特性,那关于Java8中的其他新特性内容可以参考这篇文章 《Java8新特性实战》 ;
-
那既然是Java8的新特性,而且我们也知道Java8大改动之一的就是增加了函数式编程,而Stream就主角,那有关函数式编程是什么,可以参考知乎上的一篇文章 《什么是函数式编程?》 ;
-
既然是函数式编程,所以通常是配合Lambda表达式使用;
Stream怎么用?
所有操作分类
首先Stream的所有操作可分为两类, 一是中间操作 , 二是终止操作
中间操作:中间操作只是一种标记,只有结束操作才会触发实际计算
- 无状态 :指元素的处理不受前面元素的影响;
- 有状态: 有状态的中间操作必须等到所有元素处理之后才知道最终结果,比如排序是有状态操作,在读取所有元素之前并不能确定排序结果。
终止操作:顾名思义,就是得出最后计算结果的操作
- 短路操作: 指不用处理全部元素就可以返回结果;
- 非短路操作: 指必须处理所有元素才能得到最终结果。
此外这里我看到有的地方将collect定义为了中间操作,但通过我看了大部分对Stream的介绍,发现Collect这个收集操作是最终止操作,毕竟这也符合我们平时所用到它的场景,所以还请加以辨别有的文章中提到的collect是中间操作的错误解释。
常用操作
以下两张图是对stream的常用操作做了一个简单使用案例,原本流程图在这 Java8新特性
那至于常用操作这块,本次博客也不在进行过多的细说,因为网上有很多这种使用类型的文章,我常看的有这三篇文章:
-
- 作者是不高兴就喝水,虽然这个题目名字有点不符文章内容,但内容还是很肝的,主要是一些应用例子。
-
- 作者是JavaGuide,里面简单的提了一些操作
-
- 作者是芋道源码,主要是对我们平时会用List、Set、Map这些集合类型做排序的例子
-
- 这个是自己当时在使用集合的时候看到的一篇文章,可以作为补充看看
为什么使用Stream?
声明式处理数据
第一个原因我觉得是Stream流可以以声明式的方式去处理数据,也就是像它其中就有filter、sort这种以及写好的操作,只需要拿来使用即可,如果我们平时使用for循环,还要在for循环中自己去写怎么过滤的这些操作,最后才得出自己想要的结果,对比这种命令式的操作
可以说让我们代码更加干净、简洁。
对比for循环
对于与for循环效率的对比,我觉得和以下内容差不多,但搜寻网上资料来证明某一观点正确的我目前没有找到,很多人持有观点就是“牺牲代码效率来换取代码简洁度”,“Stream的优势在于有并行处理”,“Stream的效率与for差不多,为了代码简洁更偏向Stream”等。<