六、強大的 Stream API
一、瞭解 Stream
Java8中有兩大最為重要的改變。第一個是 Lambda 表示式;另外一個則是 Stream API(java.util.stream.*)。Stream 是 Java8 中處理集合的關鍵抽象概念,它可以指定你希望對集合進行的操作,可以執行非常複雜的查詢、過濾和對映資料等操作。使用Stream API 對集合資料進行操作,就類似於使用 SQL 執行的資料庫查詢。也可以使用 Stream API 來並行執行操作。簡而言之,Stream API 提供了一種高效且易於使用的處理資料的方式。
二、什麼是 Stream
流(Stream) 到底是什麼呢?是資料渠道,用於操作資料來源(集合、陣列等)所生成的元素序列。“集合講的是資料,流講的是計算!"
注意:①Stream 自己不會儲存元素。②Stream 不會改變源物件。相反,他們會返回一個持有結果的新Stream。③Stream 操作是延遲執行的。這意味著他們會等到需要結果的時候才執行。
三、Stream 的操作三個步驟
建立 Stream一個數據源(如: 集合、陣列), 獲取一個流
中間操作一箇中間操作鏈,對資料來源的資料進行處理
終止操作(終端操作)一個終止操作,執行中間操作鏈,併產生結果
1.建立 Stream
Java8 中的 Collection 介面被擴充套件,提供了兩個獲取流的方法:
default Stream<E> stream() : 返回一個順序流
由陣列建立流Java8 中的 Arrays 的靜態方法 stream() 可以獲取陣列流: static <T> Stream<T> stream(T[] array): 返回一個流過載形式,能夠處理對應基本型別的陣列: public static IntStream stream(int[] array) public static LongStream stream(long[] array) public static DoubleStream stream(double[] array)
迭代public static<T> Stream<T> iterate(final T seed, finalUnaryOperator<T> f) 生成public static<T> Stream<T> generate(Supplier<T> s) :
2.Stream 的中間操作
多箇中間操作可以連線起來形成一個流水線,除非流水線上觸發終止操作,否則中間操作不會執行任何的處理!而在終止操作時一次性全部處理,稱為“惰性求值” 。
3.Stream 的終止操作
終端操作會從流的流水線生成結果。其結果可以是任何不是流的值,例如: List、 Integer,甚至是 void 。
Collector 介面中方法的實現決定了如何對流執行收集操作(如收集到 List、 Set、 Map)。但是 Collectors 實用類提供了很多靜態方法,可以方便地建立常見收集器例項, 具體方法與例項如下表:
四、並行流與序列流
並行流就是把一個內容分成多個數據塊,並用不同的執行緒分別處理每個資料塊的流。Java 8 中將並行進行了優化,我們可以很容易的對資料進行並行操作。 Stream API 可以宣告性地通過 parallel() 與sequential() 在並行流與順序流之間進行切換。
瞭解 Fork/Join 框架
Fork/Join 框架: 就是在必要的情況下,將一個大任務,進行拆分(fork)成若干個小任務(拆到不可再拆時),再將一個個的小任務運算的結果進行 join 彙總
Fork/Join 框架與傳統執行緒池的區別
採用 “工作竊取”模式(work-stealing):當執行新的任務時它可以將其拆分分成更小的任務執行,並將小任務加到執行緒佇列中,然後再從一個隨機執行緒的佇列中偷一個並把它放在自己的佇列中。
相對於一般的執行緒池實現,fork/join框架的優勢體現在對其中包含的任務的處理方式上.在一般的執行緒池中,如果一個執行緒正在執行的任務由於某些原因無法繼續執行,那麼該執行緒會處於等待狀態.而在fork/join框架實現中,如果某個子問題由於等待另外一個子問題的完成而無法繼續執行.那麼處理該子問題的執行緒會主動尋找其他尚未執行的子問題來執行.這種方式減少了執行緒的等待時間,提高了效能.
參考資料:
《尚矽谷JAVA8》