Java 9 Stream API的改進
1.概述
在本文的快速撰寫中,我們將重點介紹Java 9中新的有趣的Stream API改進。
2.串流收/放
關於這些方法的討論已經在StackOverflow上反復出現(最流行的一種是)。
試想一下,我們要產生一個Stream的String中加入一個字符較早前的S Stream的價值,直到這個電流值的長Stream低於10 。
我們將如何在Java 8中解決它?我們可以使用一個短路狀的中間業務limit , allMatch實際上起到用於其他目的或寫我們自己的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.
假設已經成功創建並填充了collection和map變量,請看以下示例:
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上找到代碼片段。