Stream
java8新添加了一个特性:流Stream。Stream让开发者能够以一种声明的方式处理数据源(集合、数组等),它专注于对数据源进行各种高效的聚合操作(aggregate operation)和大批量数据操作 (bulk data operation)。
Stream API将处理的数据源看做一种Stream(流),Stream(流)在Pipeline(管道)中传输和运算,支持的运算包含筛选、排序、聚合等,当到达终点后便得到最终的处理结果。
关键概念
- 元素:Stream是一个来自数据源的元素队列,Stream本身并不存储元素。
- 数据源(Stream的来源):包括集合,数组,I/Ochannel,generator(发生器)等。
- 聚合操作:类似SQL中的Filter,map,find,match,sorted等操作。
- 管道运算:Stream在Pipline中运算后返回Stream对象本身,这样多个操作串联成一个Pipeline,并形成fluent风格的代码。这种方式可以优化操作,如延迟执行(laziness)和短路( short-circuiting)。
- 内部迭代 不同于java8以前对集合的遍历方式(外部迭代),Stream API采用访问者模式(Visitor)实现了内部迭代。
- 并行运算 Stream API支持串行(stream() )或并行(parallelStream() )的两种操作方式。
Stream API的特点:
- Stream API的使用和同样是java8新特性的lambda表达式密不可分,可以大大提高编码效率和代码可读性。
- Stream API提供串行和并行两种操作,其中并行操作能发挥多核处理器的优势,使用fork/join的方式进行并行操作以提高运行速度。
- Stream API进行并行操作无需编写多线程代码即可写出高效的并发程序,且通常可避免多线程代码出错的问题。
其实Stream可以分为并行和串行两种流方式,从数据源(集合,数组等)获取到元素队列(即Stream流)后,对这些元素队列进行聚合操作,聚合操作本身是返回一个流对象,这样又可以对新的流对象进行聚合操作,这样的多个聚合操作一起组成了我们的管道运算。这就是Stream流的基本概念。
入门demo
对一个数组进行筛选操作,来初步的对StreamAPI有一个初步的了解。
public class Java8Tester {
public static void main(String[] args) {
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
list.stream().filter(n -> n > 2).forEach(System.out::println);
}
}
StreamAPI经典接口
Stream的生成
-
串行流
stream()
-
并行流
parallelStream()
在使用层次上,串行流和并行流并没有区别,只是在底层实现上,串行流
stream()
是串行进行处理的,而parallelStream
是并行进行处理的,而正是因为并行处理,所以对集合的遍历无序的。
forEach()
forEach不仅在集合中有这个接口,在Stream中也有这个接口,这个接口会接受一个Consumer对象,无返回值。我们可以通过lambda表达式来对元素进行一个操作。
public class Java8Tester {
public static void main(String[] args) {
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
list.stream().forEach((n) -> System.out.println(n<