一、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]