Java 9 Stream API的改進

1.概述

在本文的快速撰寫中,我們將重點介紹Java 9中新的有趣的Stream API改進。

2.串流收/放

關於這些方法的討論已經在StackOverflow上反復出現(最流行的一種是)。

試想一下,我們要產生一個StreamString中加入一個字符較早前的S Stream的價值,直到這個電流值的長Stream低於10

我們將如何在Java 8中解決它?我們可以使用一個短路狀的中間業務limitallMatch實際上起到用於其他目的或寫我們自己的takeWhile實現基於一個Spliterator ,反過來,這樣一個簡單的問題複雜化。

使用Java 9,該解決方案很容易:

Stream<String> stream = Stream.iterate("", s -> s + "s")

 .takeWhile(s -> s.length() < 10);

takeWhile操作採用一個Predicate ,該Predicate將應用於元素以確定這些元素的最長前綴(如果已排序流)或該流元素的子集(當未排序流時)。

為了前進,我們最好理解“最長前綴”和“ Stream's子集”這兩個術語Stream's含義:

  • 最長前綴是流中與給定謂詞匹配的元素的連續序列。序列的第一個元素是此流的第一個元素,緊接序列的最後一個元素的元素與給定謂詞不匹配
  • 一個Stream's子集為一組的一些(但不是全部)元素的Stream匹配給定的斷言。

在介紹了這些關鍵術語之後,我們可以輕鬆地理解另一個新的dropWhile操作。

它與takeWhile恰好相反。如果對流進行排序,則dropWile在刪除與給定謂詞匹配的元素的最長前綴後,將返回由該Stream其餘元素組成的Stream

否則,如果Stream是無序的,則dropWile在刪除與給定謂詞匹配的元素子集之後,將返回由該Stream其餘元素組成的Stream

讓我們使用前面獲得的Stream丟棄前五個元素:

stream.dropWhile(s -> !s.contains("sssss"));

簡而言之, dropWhile操作將刪除元素,而元素的給定謂詞返回true並停止刪除第一個謂詞的false

3.流迭代

下一個新功能是用於有限Streams生成的重載iterate方法。不要與finite變體混淆,後者會返回由某個函數生成的無限順序有序Stream

一個新的iterate通過添加一個謂詞來稍微修改此方法,該謂詞適用於確定流何時必須終止的元素。它的用法非常方便和簡潔:

Stream.iterate(0, i -> i < 10, i -> i + 1)

 .forEach(System.out::println);

它可以與相應的for語句關聯:

for (int i = 0; i < 10; ++i) {

 System.out.println(i);

 }

4.流為空

在某些情況下,我們需要將元素放入Stream 。有時,此元素可以為null ,但我們不希望我們的Stream包含此類值。它導致編寫if語句或三元運算符,以檢查元素是否為null.

假設已經成功創建並填充了collectionmap變量,請看以下示例:

collection.stream()

 .flatMap(s -> {

 Integer temp = map.get(s);

 return temp != null ? Stream.of(temp) : Stream.empty();

 })

 .collect(Collectors.toList());

為避免此類樣板代碼, ofNullable方法添加到Stream類。使用此方法,前面的樣本可以簡單地轉換為:

collection.stream()

 .flatMap(s -> Stream.ofNullable(map.get(s)))

 .collect(Collectors.toList());

5.結論

我們考慮了Java 9中Stream API的重大更改,以及這些改進如何幫助我們以更少的精力編寫更多有重點的程序。

與往常一樣,可以在Github上找到代碼片段。