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

寫在前面

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新特性時少走彎路。

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章