Java 9 Stream API 新增功能

Java 9 Stream API 新增功能

本文聚焦Java 9 Stream API 新增功能。

1. Stream Takewhile/Dropwhile

假如我們需要生成字符串流,增加一個字符至前一個流的值,直到流當前值的長度小於10.
在java8中如何實現?需要使用短路的中間操作如,limit,allMatch(實際上用於其他目的)。或者基於Spliterator實現自己的takeWhile。總之,把簡單問題複雜化。

Java9的實現非常簡單:

Stream<String> stream = Stream.iterate("", s -> s + "s")
  .takeWhile(s -> s.length() < 10);

takeWhile操作帶一個Predicate參數,其應用於元素決定在所有元素中取最長的前綴(如果流是有序的),或者流所有元素的子集(流是無序的)。

繼續學習之前最好理解“最長的前綴”和“流的子集”是什麼意思:

  • 最長的前綴:匹配條件的流中連續元素序列. 序列的第一個元素是流的第一個元素, 緊接在序列最後一個元素後面的元素與給定的謂詞不匹配。

  • “流的子集:流中匹配條件的部分元素集合。

介紹完這些關鍵術語後,我們可以較容易地理解另一個新的dropWhile操作。

它恰好是takeWhile的相反操作,如果流是有序的,dropWhile返回的流,是刪除了最長前綴後留下元素集合。如果流是無序的,dropWhile返回的流包括刪除匹配條件的子集後留下元素的集合。

使用前綴獲得流實現丟棄前五個元素:

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

簡言之,dropWhile操作刪除對於給定條件返回true的元素,並第一次遇到條件返回false停止刪除。

2. Stream Iterate

接着介紹新特性是重載iterate方法實現有限流生成。不要與另一個重載static <T> Stream<T> iterate(T seed, UnaryOperator<T> f)方法混淆,其返回有函數生成的無限順序序列流。

新的iterate增加了一個predicate決定生成流什麼條件必須終止,其使用很方便、簡潔:

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);
}

3. Stream Ofnullable

有時添加至流中的元素可能爲null,我們並不希望這樣值存在流中。因此需要些if條件語句或三元運算符檢查元素是否爲null。

假如我們有collection 和 map 變量,內容如下:

List<String> collection = Arrays.asList("A", "B", "C");
Map<String, Integer> map = new HashMap<>() {
    {
        put("A", 10);
        put("C", 30);
    }
};

請看下面示例:

collection.stream()
  .flatMap(s -> {
      Integer temp = map.get(s);
      return temp != null ? Stream.of(temp) : Stream.empty();
    })
  .collect(Collectors.toList());

這裏需要判斷temp是否爲null,導致flatMap方法過於冗長。爲了避免使用Stream類的ofNullable方法,相同功能代碼非常簡潔:

collection.stream()
  .flatMap(s -> Stream.ofNullable(map.get(s)))
  .collect(Collectors.toList());

4. 總結

本文介紹了Java 9 Stream Api中新增的方法,這些增強功能會幫助使用更少的代碼實現強大功能。

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