Java 流式编程stream
目錄
- 什么是Stream?
- 怎么創建Stream?
- Stream的中間操作
- Stream的終端操作
什么是Stream?
Stream它并不是一個容器,它只是對容器的功能進行了增強,添加了很多便利的操作,例如查找、過濾、分組、排序等一系列的操作。并且有串行、并行兩種執行模式,并行模式充分的利用了多核處理器的優勢,使用fork/join框架進行了任務拆分,同時提高了執行速度。簡而言之,Stream就是提供了一種高效且易于使用的處理數據的方式。
- 特點:
- Stream自己不會存儲元素。
- Stream的操作不會改變源對象。相反,他們會返回一個持有結果的新Stream。
- Stream 操作是延遲執行的。它會等到需要結果的時候才執行。也就是執行終端操作的時候。
一個Stream的操作就如上圖,在一個管道內,分為三個步驟,第一步是創建Stream,從集合、數組中獲取一個流,第二步是中間操作鏈,對數據進行處理。第三步是終端操作,用來執行中間操作鏈,返回結果。
怎么創建Stream?
-
由集合創建:
Java8 中的 Collection 接口被擴展,提供了兩個獲取流的方法,這兩個方法是default方法,也就是說所有實現Collection接口的接口都不需要實現就可以直接使用:default Stream stream() : 返回一個順序流。
default Stream parallelStream() : 返回一個并行流。
例如:
-
由數組創建:
Java8 中的 Arrays 的靜態方法 stream() 可以獲取數組流:static Stream stream(T[] array): 返回一個流
重載形式,能夠處理對應基本類型的數組:
public static IntStream stream(int[] array)
public static LongStream stream(long[] array)
public static DoubleStream stream(double[] array)
- 由值創建:
可以使用靜態方法 Stream.of(), 通過顯示值 創建一個流。它可以接收任意數量的參數。
public static Stream of(T… values) : 返回一個流。
- 可以使用靜態方法 Stream.iterate() 和 Stream.generate()創建無限流。
迭代
public static Stream iterate(final T seed, final UnaryOperator f)
生成
public static Stream generate(Supplier s)
注意:使用無限流一定要配合limit截斷,不然會無限制創建下去。
Stream的中間操作
如果Stream只有中間操作是不會執行的,當執行終端操作的時候才會執行中間操作,這種方式稱為延遲加載或惰性求值。多個中間操作組成一個中間操作鏈,只有當執行終端操作的時候才會執行一遍中間操作鏈,具體是因為什么我們在后面再說明。下面看下Stream有哪些中間操作。
-
Stream distinct():
去重,通過流所生成元素的 hashCode() 和 equals() 去除重復元素。
-
Stream filter(Predicate<? super T> predicate):
Predicate函數,它是斷言型接口,所以filter方法中是接收一個和Predicate函數對應Lambda表達式,返回一個布爾值,從流中過濾某些元素。
-
Stream sorted(Comparator<? super T> comparator):
指定比較規則進行排序。
-
Stream limit(long maxSize):
截斷流,使其元素不超過給定數量。如果元素的個數小于maxSize,那就獲取所有元素。
-
Stream skip(long n):
-
Stream map(Function<? super T, ? extends R> mapper):
接收一個Function函數作為參數,該函數會被應用到每個元素上,并將其映射成一個新的元素。也就是轉換操作,map還有三個應用于具體類型方法,分別是:mapToInt,mapToLong和mapToDouble。這三個方法也比較好理解,比如mapToInt就是把原始Stream轉換成一個新的Stream,這個新生成的Stream中的元素都是int類型。這三個方法可以免除自動裝箱/拆箱的額外消耗。
-
Stream flatMap(Function<? super T, ? extends Stream<? extends R>> mapper):
接收一個Function函數作為參數,將流中的每個值都轉換成另一個流,然后把所有流連接成一個流。flatMap也有三個應用于具體類型的方法,分別是:flatMapToInt、flatMapToLong、flatMapToDouble,其作用于map的三個衍生方法相同。
Stream的終端操作
終端操作執行中間操作鏈,并返回結果。終端操作我們就不一一介紹了,只介紹一下常用的操作。詳細可看java.util.stream.Stream接口中的方法。
- void forEach(Consumer<? super T> action):
-內部迭代(需要用戶去做迭代,稱為外部迭代。相反,Stream API使用內部迭代幫你把迭代做了)
- <R, A> R collect(Collector<? super T, A, R> collector):
收集、將流轉換為其他形式,比如轉換成List、Set、Map。collect方法是用Collector作為參數,Collector接口中方法的實現決定了如何對流執行收集操作(如收集到 List、Set、Map)。但是 Collectors 實用類提供了很多靜態方法,可以方便地創建常見收集器實例。例舉一些常用的:
-
其他終端操作:
- boolean allMatch(Predicate<? super T> predicate); 檢查是否匹配所有元素。
- boolean anyMatch(Predicate<? super T> predicate); 檢查是否至少匹配一個元素。
- boolean noneMatch(Predicate<? super T> predicate); 檢查是否沒有匹配所有元素。
- Optional findFirst(); 返回當前流中的第一個元素。
- Optional findAny(); 返回當前流中的任意元素。
- long count(); 返回流中元素總數。
- Optional max(Comparator<? super T> comparator); 返回流中最大值。
- Optional min(Comparator<? super T> comparator); 返回流中最小值。
- T reduce(T identity, BinaryOperator accumulator); 可以將流中元素反復結合起來,得到一個值。 返回 T。這是一個歸約操作。
總結
以上是生活随笔為你收集整理的Java 流式编程stream的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: linux驱动加载模块可以用哪个命令(l
- 下一篇: Java 泛型实现方法 — 擦拭法