Java 9 Stream APIの改善

1概要

この記事では、Java 9で新たに登場したStream APIの改良点について説明します。

2 Stream takeWhile/dropWhile

これらの方法についての議論は、http://stackoverflow.com/[StackOverflow](http://stackoverflow.com/questions/20746429/limit-a-stream-by-a-predicate[this One)で繰り返し公開されています])。

この Stream の現在の値の長さが 10 より小さくなるまで、前の Stream の値に1文字を追加して、 Stream Stream を生成するとします。

Java 8でそれをどのように解決しますか? https://docs.oracle.com/javase/8/docs/api/java/util/stream/Stream.html#limit-long -[ limit ]、httpsのような短絡中間操作の1つを使用できます。//docs.oracle.com/javase/8/docs/api/java/util/stream/Stream.html#allMatch-java.util.function.Predicate-[ allMatch ]実際に他の目的に役立つか、または独自のhttpを書くhttps://docs.oracle.com/javase/8/docs/api/java/util/Spliterator.html[ Spliterator ]に基づいて、//stackoverflow.com/a/20765715/4922375[ takeWhile 実装]ターン、そのような単純な問題を複雑にします。

Java 9では、解決策は簡単です。

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

takeWhile 操作は、要素に適用される Predicate を使用して、これらの要素の最長の接頭辞(ストリームが順序付けられている場合)またはストリームの要素のサブセット(ストリームが順序付けされていない場合)を決定します。

先に進むために、「最長プレフィックス」と「 Stream’s サブセット」という用語の意味を理解しておく必要があります。

  • 最長の接頭辞 は、の連続する要素のシーケンスです。

与えられた述語にマッチするストリーム。シーケンスの最初の要素 このストリームの最初の要素で、すぐその要素 シーケンスの最後の要素に続くものが与えられたものと一致しない 述語 Stream’s サブセット** は、のすべての要素ではなく一部の要素の集合です。

Stream は与えられた述語にマッチします。

これらの重要な用語を紹介した後、別の新しい dropWhile 操作を簡単に理解することができます。

それは takeWhile の正反対です。ストリームが順序付けられている場合、 dropWile は、指定された述語に一致する要素の最長プレフィックス を削除した後、この Stream の残りの要素で構成されるストリームを返します。

そうではなく、 Stream が順序付けられていない場合、 dropWile は、指定された述語に一致する要素のサブセット を削除した後で、この Stream の残りの要素で構成されるストリームを返します。

先ほど取得した Stream を使用して最初の5つの要素を捨てましょう。

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

簡単に言うと、 dropWhile 操作は要素を削除しますが、与えられた要素の述語は true を返し、最初の述語の false で削除を停止します。

3 Stream 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 ofNullable

要素を 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());

このような定型コードを回避するために、https://docs.oracle.com/javase/9​​/docs/api/java/util/stream/Stream.html#ofNullable-T-[ ofNullable ]メソッドが Stream クラスに追加されました。この方法では、前のサンプルを次のように簡単に変換できます。

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

5結論

Java 9におけるStream APIの大きな変更点と、これらの改善点が、より少ない労力でより力強いプログラムを書くのにどのように役立つかを検討しました。

いつものように、コードスニペットはhttps://github.com/eugenp/tutorials/tree/master/core-java-9[Githubへの追加]にあります。