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への追加]にあります。