一、Stream概述
Java 8 是一个非常成功的版本,这个版本新增的Stream
,配合同版本出现的 Lambda
,给我们操作集合(Collection)提供了极大的便利。
Stream可以将处理的元素集合看作一种流,在流的过程,借助Stream API对流的元素进行操作,比如:排序、筛选、聚合、去重等等。
Stream
可以由数组或集合创建,对流的操作分为两种:
- 中间操作,每次返回一个新的流,可以有多个。
- 终端操作,每个流只能进行一次终端操作,终端操作结束后流无法再次使用。终端操作会产生一个新的集合或值。
二、Stream的创建
Stream 可以通过集合数组创建
1、通过 java.util.Collection.stream()
方法用集合创建流
List<String> list = Arrays.asList("a", "b", "c");
// 创建一个顺序流
Stream<String> stream = list.stream();
// 创建一个并行流
Stream<String> parallelStream = list.parallelStream();
复制代码
2、使用java.util.Arrays.stream(T[] array)
方法用数组创建流
int[] array={1,3,5,6,8};
IntStream stream = Arrays.stream(array);
复制代码
3、使用Stream
的静态方法:of()、iterate()、generate()
Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5, 6);
Stream<Integer> stream2 = Stream.iterate(0, (x) -> x + 3).limit(4);
stream2.forEach(System.out::println);
Stream<Double> stream3 = Stream.generate(Math::random).limit(3);
stream3.forEach(System.out::println);
stream
和
parallelStream
的简单区分:
stream
是顺序流,由主线程按顺序对流执行操作,而
parallelStream
是并行流,内部以多线程并行执行的方式对流进行操作,但前提是流中的数据处理没有顺序要求。例如筛选集合中的奇数,两者的处理不同之处:
- steam()是串行流,是进行无序的处理
- parallelStream()为集合创建并行流,对于ParallelStream,需要知道的是里面的执行是异步的,并且使用的线程池是ForkJoinPool.common,可以通过设置-Djava.util.concurrent.ForkJoinPool.common.parallelism = N来调整线程池的大小;
Stream具有平行处理能力,处理的过程会分而治之,也就是将一个大任务切分成多个小任务,这表示每个任务都是一个操作。
注意: Java8并行流parallelStream()和stream()的区别就是支持并行执行,提高程序运行效率。但是如果使用不当可能会发生线程安全的问题。
三、Stream的使用
在使用stream之前,先理解一个概念:Optional
。
Optional
类是一个可以为null
的容器对象。如果值存在则isPresent()
方法会返回true
,调用get()
方法会返回该对象。 更详细说明请见:菜鸟教程Java 8 Optional类
接下来,我会采用一大批常见的案例说明Stream如何使用,当我们用好了Stream你会发现代码效果原来这么好~~~
3.1 遍历/匹配 (foreach/find/match)
3.2 筛选
案例一:筛选出Integer
集合中大于7的元素,并打印出来
预期结果:
9
8
20
案例二: 筛选员工中工资高于8000的人,并形成新的集合。 形成新集合依赖collect
(收集)
预期结果:
月薪大于8000的员工有:[Tom, Anni, Owen]