介绍
Stream是Java 8中引入的新特性,它是一个用于描述对集合、数组等数据进行处理的API。它可以极大的简化集合类(包括数组)的处理操作,并且提供了强大的功能,比如过滤、转换、排序、聚合等。
原则
- 声明式:Stream的操作不涉及底层数据存储和实现细节,更侧重于描述要执行的操作。
- 可组合:可以将多个操作连接起来,形成一个链式操作(在终止操作遍历时,根据先后顺序执行多个操作)。
- 延迟执行:Stream的中间操作只有在终止操作(如forEach)时才会执行。
原理
- 创建一个Stream对象,可以通过集合、数组等方式来创建。
- 中间操作,对Stream对象进行一系列的操作,比如过滤、映射、排序等操作,这些操作可以串联起来形成一个Pipeline(管道)。
- 终端操作,最后执行终止操作,触发流的执行,得到结果。
特点
- Stream不会改变源数据,所有的操作都是基于数据源的一个新的视图(理解:相当于对一个新的集合继续操作)
- Stream的操作可以进行优化,如并行执行等,提高了数据处理的效率
注意事项
- Stream的操作是延迟执行的,需要注意终止操作的使用时机,否则可能出现数据不完整的情况。
- Stream的操作不会改变源数据,需要注意收集操作的使用时机,否则可能造成数据的浪费。
- Stream操作可以链式调用,但终端操作只能有一个。
- Stream可以并行处理,提高处理效率。但需要注意线程安全问题。
Stream创建方式(三种)
Stream<T> stream = collection.stream(); // 通过集合创建Stream
Stream<T> stream = Arrays.stream(arr); // 通过数组创建Stream
Stream<T> stream = Stream.of(t1, t2, t3); // 直接创建Stream
常见API
常用API方法
在JDK中,提供了非常丰富的API方法,主要分为以下两类:
延迟方法(中间操作)
返回值类型仍然为Stream接口自身类型的方法,因此支持链式调用。如:
- 筛选与切片
- filter:过滤出符合条件的元素
- limit:截断流,使其元素不超过给定数量
- skip:跳过前n个元素,返回剩下的元素
- distinct:去重,根据元素的hashCode()和equals()方法实现
- 映射
- map:将元素按照指定的方式转换
- mapToDouble:将元素转换为double类型
- mapToInt:将元素转换为int类型
- mapToLong:将元素转换为long类型
- flatMap:将元素按照指定的方式转换,返回一个流
- 排序
- sorted:自然排序
- sorted(Comparator comparator):自定义排序
- 组合:
- concat:连接两个流
终结方法:返回值类型不再是Stream接口自身类型的方法。
返回元素的返回类型为Optional<Stream的T类型>
- 遍历:
- forEach:对每个元素执行操作
- 匹配与查找
- allMatch:检查是否匹配所有元素
- anyMatch:检查是否至少匹配一个元素
- noneMath:检查是否没有匹配所有元素
- findFirst:返回第一个元素
- findAny:返回当前流中的任意元素
- 统计
- count:返回流中元素的总数
- max:返回流中最大值
- min:返回流中最小值
- 归约:
- reduce:对流中的元素按照指定的方式进行归约操作
- 收集:
- collect:将流转换为集合或Map等其他类型
- 分组:
- groupingBy:按照指定的条件对流进行分组