【Java8新特性】關於Java8的Stream API,看這一篇就夠了!!

冰河團隊發表於2020-05-23

寫在前面

Java8中有兩大最為重要的改變。第一個是 Lambda 表示式;另外一個則是 Stream API(java.util.stream.*) ,那什麼是Stream API呢?Java8中的Stream又該如何使用呢?

什麼是Stream?

Java8中有兩大最為重要的改變。第一個是 Lambda 表示式;另外一個則是 Stream API(java.util.stream.*)。

Stream 是 Java8 中處理集合的關鍵抽象概念,它可以指定你希望對集合進行的操作,可以執行非常複雜的查詢、過濾和對映資料等操作。使用Stream API 對集合資料進行操作,就類似於使用 SQL 執行的資料庫查詢。也可以使用 Stream API 來並行執行操作。簡而言之,Stream API 提供了一種高效且易於使用的處理資料的方式

流是資料渠道,用於運算元據源(集合、陣列等)所生成的元素序列。“集合講的是資料,流講的是計算! ”

注意:
① Stream 自己不會儲存元素。
② Stream 不會改變源物件。相反,他們會返回一個持有結果的新Stream。
③ Stream 操作是延遲執行的。這意味著他們會等到需要結果的時候才執行。

Stream操作的三個步驟

  • 建立 Stream

一個資料來源(如: 集合、陣列), 獲取一個流。

  • 中間操作

一箇中間操作鏈,對資料來源的資料進行處理。

  • 終止操作(終端操作)

一個終止操作,執行中間操作鏈,併產生結果 。

在這裡插入圖片描述

如何建立Stream?

Java8 中的 Collection 介面被擴充套件,提供了兩個獲取流的方法:

1.獲取Stream

  • default Stream stream() : 返回一個順序流

  • default Stream parallelStream() : 返回一個並行流

2.由陣列建立Stream

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)

3.由值建立流

可以使用靜態方法 Stream.of(), 通過顯示值建立一個流。它可以接收任意數量的引數。

  • public static Stream of(T... values) : 返回一個流

4.由函式建立流

由函式建立流可以建立無限流。

可以使用靜態方法 Stream.iterate() 和Stream.generate(), 建立無限流 。

  • 迭代

public static Stream iterate(final T seed, final UnaryOperator f)

  • 生成

public static Stream generate(Supplier s)

Stream的中間操作

多箇中間操作可以連線起來形成一個流水線,除非流水線上觸發終止操作,否則中間操作不會執行任何的處理!而在終止操作時一次性全部處理,稱為“惰性求值”

1.篩選與切片

在這裡插入圖片描述

2.對映

在這裡插入圖片描述

3.排序

在這裡插入圖片描述

Stream 的終止操作

終端操作會從流的流水線生成結果。其結果可以是任何不是流的值,例如: List、 Integer,甚至是 void 。

1.查詢與匹配

在這裡插入圖片描述

在這裡插入圖片描述

2.規約

在這裡插入圖片描述

3.收集

在這裡插入圖片描述

Collector 介面中方法的實現決定了如何對流執行收集操作(如收集到 List、 Set、 Map)。但是 Collectors 實用類提供了很多靜態方法,可以方便地建立常見收集器例項, 具體方法與例項如下表

在這裡插入圖片描述

在這裡插入圖片描述

並行流與序列流

並行流就是把一個內容分成多個資料塊,並用不同的執行緒分別處理每個資料塊的流。

Java 8 中將並行進行了優化,我們可以很容易的對資料進行並行操作。 Stream API 可以宣告性地通過 parallel() 與
sequential() 在並行流與順序流之間進行切換

Fork/Join 框架

1.簡單概述

Fork/Join 框架: 就是在必要的情況下,將一個大任務,進行拆分(fork)成若干個小任務(拆到不可再拆時),再將一個個的小任務運算的結果進行 join 彙總.

在這裡插入圖片描述

2.Fork/Join 框架與傳統執行緒池的區別

採用 “工作竊取”模式(work-stealing):
當執行新的任務時它可以將其拆分分成更小的任務執行,並將小任務加到執行緒佇列中,然後再從一個隨機執行緒的佇列中偷一個並把它放在自己的佇列中。

相對於一般的執行緒池實現,fork/join框架的優勢體現在對其中包含的任務的處理方式上.在一般的執行緒池中,如果一個執行緒正在執行的任務由於某些原因無法繼續執行,那麼該執行緒會處於等待狀態.而在fork/join框架實現中,如果某個子問題由於等待另外一個子問題的完成而無法繼續執行.那麼處理該子問題的執行緒會主動尋找其他尚未執行的子問題來執行.這種方式減少了執行緒的等待時間,提高了效能。

寫在最後

如果覺得文章對你有點幫助,請微信搜尋並關注「 冰河技術 」微信公眾號,跟冰河學習Java8新特性。

最後,附上Java8新特性核心知識圖,祝大家在學習Java8新特性時少走彎路。

在這裡插入圖片描述

相關文章