Java Stream API實用指南

StreamAPI是在Java 8中引入的。它提供了一種聲明性編程方法,用於迭代和執行集合上的操作。在Java 7及之前版本中,for和for each是唯一遍歷集合的可用選項,這是一種 命令式編程方法。在本文中,我將向您介紹StreamAPI以及它如何提供對集合執行的常見操作的抽象。

在使用命令式編程時,開發人員使用語言結構來編寫 要執行的操作和操作方法。在使用聲明性編程時,開發人員必須只關注定義要做什麼,語言或框架負責如何做部分。因此,在聲明性編程中,代碼簡潔且不易出錯。

通常在集合上執行的操作可以分類如下。雖然下面的列表並不詳盡,但它涵蓋了我們在日常編程中遇到的大多數用例。我將在示例中使用下面提到的操作來介紹StreamAPI。

  • 轉換
  • 過濾
  • 搜索
  • 重新排序
  • 統計總和
  • 分組分類

在示例中,我將使用一組Person對象。爲了便於理解,Person 該類的定義如下所示:

快速介紹Stream API

在深入研究使用Stream API對集合執行的操作示例之前,讓我們使用一個示例來了解Stream API本身。

在上面的示例中,多個操作被鏈接在一起以形成類似處理管道的東西。這就是我們所說的流管道pipelining。流管道由以下三部分組成:

  • 流構建器 - 在上面的示例中,我們有一個由Person表示的集合people。在Collection接口上添加方法來構建Java 8中stream() 的流。除了Collection是流的常見源之外,還有數組(Arrays.stream())和生成器函數(Stream.iterate() 和Stream.generate())。
  • 中間操作 - 創建流對象後,您可以通過鏈接操作在流上應用零或一個或多個操作,就像在構建器模式中一樣。所有你在上面的例子中看到的方法:filter和map,它們被稱爲中間操作。
  • 終端操作 - 一旦應用了所有計算,您就可以通過應用強制終端運算符來完成管道。終端操作符也是Stream接口上的方法,返回的不是Stream的結果類型。在上面的示例中,collect(Collectors.toList())返回一個實例List。結果類型可以是任意集合。

現在讓我們看一下使用Stream可以執行的基本操作。雖然我們將瞭解在Stream上單獨應用的操作,但您始終可以混合和匹配它們以獲得不同的結果。

轉換

轉換意味着轉換存儲在集合的每個元素中的值的類型。假設我們想要從人物集合中獲取人物名稱的集合。在這種情況下,我們必須使用轉換操作將人轉換爲名稱。

在下面的示例中,我們使用map這個中間運算符轉換People爲人的名稱,人的名稱是String類型。Person::getName是一個方法引用,它等同於 person -> person.getName()並且是Function的一個實例。

過濾

正如過濾這個文字所暗示的那樣,只有當對象滿足謂詞所規定的條件時,過濾操作才允許對象流過自身。過濾器運算符由Predicate它應用於Stream之前組成。

過濾也可以被認爲是基於計數選擇少量元素。流API提供skip()和limit()運營商用於這一目的。

在下面的第一個示例中,person -> person.getAge() < 20謂詞用於構建僅包含20歲以下人員的集合。在下面的第二個示例中,在跳過前2個後選擇後面的10個人。

搜索

搜索集合意味着基於標準搜索元素或元素的存在,該標準可再次表示爲一個Predicate。搜索元素可能會也可能不會返回值,因此您將獲得一個Optional. 。搜索元素的存在將返回a boolean。

在下面的示例中,使用搜索元素並使用findAny()搜索存在來完成搜索anyMatch()。

重新排序

如果要對集合中的元素進行排序,可以使用sorted中間運算符。它需要一個Comparator接口的實例。爲了創建實例,我使用了帶有comparing工廠方法的Comparator。

在下面的示例中,生成的集合按年齡降序排序。

與我們迄今爲止看到的其他操作不同,sorted操作是有狀態的。這意味着操作員必須在排序結果可以提供給進一步的中間或終端操作之前查看流中的所有元素。另一個例子是distinct

統計合併

有時您想從集合中獲取信息。例如,推導出所有人的年齡總和。在StreamAPI中,這是使用終端操作符實現的。reduce和collect都是爲此目的提供的通用終端操作。高水平的人也很喜歡sum,count,summaryStatistics,等,它們在建立reduce和collect之上。

reduce並且collect是 Reduction合併操作。reduce用於不可變的合併,collect而是用於可變的合併。不可逆的合併是首選方法,這對於性能很重要。

分組

分組也可以稱爲分類。有時我們想要將一個集合分成幾個組。在這種情況下得到的數據結構是Map鍵表示分組因子,值表示特定組的特徵。StreamAPI提供Collectors.groupingBy用於這種情形。

在下面的所有示例中,分組是使用性別完成的。不同之處在於值。

在第一個示例中,Person爲每個組創建了一個集合。在第二個中,Collectors.mapping()用於提取每個名稱Person以創建名稱集合。在第三個中,Person提取每個的年齡並計算每個組的平均年齡。

總結

在本指南中,我們看到Java StreamAPI提供了許多內置功能,以幫助使用流管道對集合執行操作。API是聲明性的,它使代碼精確且不易出錯。我希望本指南爲您提供足夠的信息,以便您Stream在日常編程中有效地使用Java API。

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