介绍
Java 8 新增了一个新的抽象称为流Stream,个人感觉这个超级好用,尤其是业务开发,经常需要对数据列表进行处理的时候,用更少的代码、更优雅地实现功能。
这个流式操作,更像是Linux中的管道命令’|’,上一个操作的结果传送到下一个流程中继续处理,例如:
|
|
在java代码实现
|
|
什么是Stream
Stream(流)是一个来自数据源的元素队列并支持聚合操作
- 元素是特定类型的对象,形成一个队列。Java中的Stream并不会存储元素,而是按需计算。
- 数据源 流的来源可以是集合、数组、I/O Channel等
- 聚合操作 类似SQL语句,比如filter、map、reduce、find、match、sorted等
和以前的Collection操作不同,Stream还有两个基础特征:
- Pipelining:中间操作都会返回流对象本身。这样多个操作可以串联成一个管道。
- 内部迭代:以前对集合遍历都是通过Iterator或者For-Each的方式,显示的在集合外部进行迭代。Stream提供了内部迭代的方式,通过访问者模式(Visitor)实现。
生成流
在Java8中,集合接口有两个方法生成流:
- stream() : 为集合创建串行流。
- parallelStream() - 为集合创建并行流。
这里要讲一下这两者的区别:
通俗点来说,一个是单线程、另一个是多线程。parallelStream是一个并行执行的流,通过默认的ForkJoinPool,可以提高多线程任务的速度。处理的过程会分而质之,将一个大任务切分成多个小任务,然后将结果合起来。(当然这也是一把双刃剑,在多线程的情况下,数据的并发访问需要关注,这也可以好好学一下,等之后再看吧~)
forEach
以前都是显示的使用循环,例如对一个集合进行打印:
JDK7以前
JDK8之后
对比一下,发现只需要一行代码就能实现~
如果想在forEach中进行自定义的操作,可以创建一个类,实现Consumer函数接口,传递进去使用~
map
map方法用于映射每个元素到对应的结果:
|
|
Car类:
filter
如其名,filter就是用来过滤的,根据特定的条件来过滤元素:
|
|
上面的例子是用来过滤出整数列表中,值大于10的数量。
limit
用来获取指定数量的流(类似于MySQL中的limit):
|
|
sorted
用来对流进行排序,类似于Collections.sort(list, Comparator);
|
|
Collectors
Collectors类实现了很多规约操作,例如将流转换成集合和聚合元素。(一般用Collectors.toList()就够了)
|
|
统计statistics
这个功能比较少用,还是学习记录一下吧。
完整的测试代码
|
|
小结
JDK的流式处理真的是太方便了(虽然以前的代码可以显示的调用,但感觉使用更少的代码来实现更加优雅😁)