简单介绍
jdk1.8中除了提供lambda表达式,剩余的一个比较大的特性就是stream流了。
stream就是针对集合进行一些列的操作,例如过滤、提取、排序、截取、分组等等,让java程序对集合的操作更加方面,至于效率问题,没有做过测试,但是说法比较多,又说效率高的,有说效率低的。同时stream流的书写跟Lambda表达式结合的很紧密,参数基本都是函数式接口,所以不了解Lambda表达的,可能不太懂stream的书写方式。
使用stream流分为三步:开启流->中间操作->终止操作
在stream流操作的整个过程中,只有当进行终止操作的时候,stream流才开始对集合进行处理,否则中间不会执行任何处理,这个特性叫做“惰性求值”。
Stream API 的分类
一、开启流
集合开启流的方法比较简单,下面简单介绍各种起开流的方式。
1、使用 集合.stream() 或者 集合.parallelStream(),后者是开启一个并行流(后面会对并行和串行流做说明)。
2、将数组转换为流,使用Arrays中的.stream(数组)的方法
3、使用stream中的静态方法,其中stream2、stream3 都是无限流,可以使用limit进行截取
4、使用BufferReader.lines(),把文件内容输出成流
5、pattern.splitAsStream()把字符串按照某个字符转换成流
以上是几种开启流的方法,其中最常用的应该是第一种,因为在日常工作中,大部分使用流的地方都是对集合进行操作。
二、中间操作
1、筛选与切片
名称 | 用途 |
filter | 对集合进行过去,参数是 Predicate<? super T> predicate |
limit | 取集合前几位,参数是给定数值 |
skip | 跳过集合几位,参数是给定数值 |
distinct | 排重,但是使用元素的hashCode()和equals()方法 |
首先过滤出年龄大于20的,共7条数据,返回前5条,跳过前两条,所以返回的就是 第3、4、5条数据。
当User实体中没有实现 hashCode 和 equals 的时候,是无法进行排重的,加上@Data注解(lombok自动帮助实现),就可排重了
2、映射
名称 | 用途 |
map | 将接受的方法,应用到每一个元素上,映射成一个新的元素 Function<? super T, ? extends R> mapper |
flatMap | 如果形成元素是一个集合,则获取出这个集合中的每一个元素放入返回结果中 |
他们俩的区别,类似于 list 的add() 和 addAll()
提取出list中user的名称,可以看到 map提取功能很好用。也可以针对每隔元素进行操作,并返回元素。
下面看一下 map 和 flatmap的不同,跟上面说的一样其实就是flatmap把返回集合的每隔元素都放入的stream流中了,map则是把集合作为一个元素放入进去
3、排序
名称 | 用途 |
sorted | 自然排序 |
sorted | 定制排序,参数 Comparator<? super T> comparator |
三、Stream的终止操作
1、查找与匹配
名称 | 用途 |
allMatch | 是否所有元素匹配 |
anyMatch | 检查是否至少一个元素匹配 |
noneMatch | 是否没有元素匹配 |
findFirst | 返回第一个元素 |
findAny | 返回当前流中任意的元素 |
count | 返回流中元素的个数 |
max | 返回流中最大值 |
min | 返回流中最小值 |
jdk1.8为了避免空指针异常,增加了optional。
2、规约
名称 | 用途 |
reduce | 可以将流中的元素按照指定模型计算到一个结果中 |
3、收集,这类的Stream是经常使用到的。因为在业务代码中,经常处理一个集合产生另外的一个集合。
名称 | 用途 |
collect | 接受一个Collectors的静态工具类,里面有很多常规操作 |
下面着重说一下 Collectors 的静态方法:
方法 | 参数 | 用途 |
| 无 | 统计个数 |
| ToDoubleFunction<? super T> | 求平均值(除了Double,还有其他类型) |
| ToDoubleFunction<? super T> | 求和 |
| Comparator<? super T> | 根据条件获取最大元素 |
| Function<? super T, ? extends K> | 按照某个条件分组 |
| Predicate<? super T> | 按照某个条件分区(true、false) |
summarizingDouble | ToDoubleFunction<? super T> | 获取某个字段的平均值、总数、最大值、最小值等 返回 DoubleSummaryStatistics |
joining | 无 | 连接字符串 |
可以看到 Stream 流让对集合的操作更加便利,之后的查找、分组、排序、拼接字符串、求值等都可以使用stream流来处理了。