1、介绍
- Stream流是用于操作数据源如集合、数组等所生成的元素序列;集合是用于存储数据,而流是用于对集合内的数据进行计算。
- Stream不是数据结构,不会保存数据。
- Stream不会修改原来的数据源,它会将操作后的数据保存到另外一个新的对象中。
- Stream是惰性求值,流在中间处理过程中,只是对操作进行了记录,并不会立即执行,需要等到执行终止操作的时候才会进行实际的计算。
- Stream可以帮助我们更加聚焦于我们要做的事,而不需要去关注具体做的过程,简化代码,提高开发效率。
如,我们要获取一个类实现的所有接口,并将其打印输出:
Class<ArrayList> arrayListClass = ArrayList.class;
Class<?>[] interfaces = arrayListClass.getInterfaces();
for(Class clazz: interfaces){
System.out.println(clazz.getName());
}
复制代码
而要达到同样的效果,我们不需要使用 for 循环同样也可以实现。
Class<ArrayList> arrayListClass = ArrayList.class;
Class<?>[] interfaces = arrayListClass.getInterfaces();
Arrays.stream(interfaces).forEach(clazz -> System.out.println(clazz.getName()));
复制代码
2、Stream的操作流程
- Stream操作的三个步骤:
创建Stream
一个数据源(集合、数组),获取一个流。
如上边例子中的 Arrays.stream(interfaces)
将一个数组转化为流。
中间操作
一个中间操作链,对数据源的数据进行处理;当需要进行多次操作时,处理过程可以采用链式衔接,从左向右顺序执行。
可以理解为对原始数据进行清洗过滤等操作。
终止操作
一个终止操作,执行中间操作链,并产生结果。
可以理解为对经过清洗过滤后的数据,想要得到什么结果或实现怎么样的操作。
比如例子中的 forEach()
遍历所有数据并打印输出。
3、Stream 的操作分类
Stream 操作分类 | ||
创建操作 | stream() | |
中间操作 | 无状态 | Filter() |
map() | ||
peek() | ||
flatMap() | ||
有状态 | distinct() | |
sorted() | ||
limit() | ||
skip() | ||
结束操作 | 非短路操作 | forEach() |
toArray() | ||
reduce() | ||
max() | ||
min() | ||
count() | ||
collect() | ||
短路操作 | findFirst() | |
findAny() | ||
allMatch() | ||
anyMatch() | ||
noneMatch |
1.无状态:指当前操作元素的处理不受之前元素的影响。如 filter() 方法,仅对当前元素进行处理。
2.有状态:指该操作只有拿到所有元素之后才能继续下去。如 sort() 方法,需要拿到所有元素后,才能进行排序操作。
3.非短路操作:指必须处理所有元素才能得到最终结果。如元素遍历,需要获取流中所有元素后才能结束。
4.短路操作:指遇到某些符合条件的元素就可以得到最终结果,如查找第一个或最后一个元素,不需要获取所有元素,当条件达成后就可以直接将结果返回。