1. 概要

Java Stream APIは、Java8リリースの主要な機能でした。 Streams は、遅延評価されたオブジェクトのシーケンスを表し、リッチで流暢なモナディックのようなAPIを提供します。

この記事では、の最後の要素を取得する方法について簡単に説明します。 ストリーム。 それを念頭に置いてストリームの性質上、自然な操作ではありません 。 無限のストリームを使用していないことを常に確認してください。

2. ReduceAPIを使用する

Reduce は、簡単に言えば、Stream内の要素のセットを単一の要素に削減します。

この場合、要素のセットを減らして、最後の要素を取得します。 ストリーム。 それを念頭に置いてこのメソッドは、シーケンシャルストリームの決定論的結果のみを返します。

String値のListを使用し、ListからStreamを取得して、以下を減らします。

List<String> valueList = new ArrayList<>();
valueList.add("Joe");
valueList.add("John");
valueList.add("Sean");

Stream<String> stream = valueList.stream();
stream.reduce((first, second) -> second)
  .orElse(null);

ここでは、ストリームは最後の要素のみが残るレベルに縮小されます。 ストリームが空の場合、null値を返します。

2. スキップ機能の使用

ストリームの最後の要素を取得するもう1つの方法は、その前のすべての要素をスキップすることです。 これは、StreamクラスのSkip関数を使用して実現できます。 この場合、 Stream を2回消費しているため、パフォーマンスに明らかな影響があります

文字列値のListを作成し、その size 関数を使用して、最後の要素に到達するためにスキップする要素の数を決定しましょう。

skipを使用して最後の要素を取得するサンプルコードは次のとおりです。

List<String> valueList = new ArrayList<String>();
valueList.add("Joe");
valueList.add("John");
valueList.add("Sean");

long count = valueList.stream().count();
Stream<String> stream = valueList.stream();
   
stream.skip(count - 1).findFirst().get();

「Sean」が最後の要素になります。

4. 無限ストリームの最後の要素を取得する

無限ストリームの最後の要素を取得しようとすると、無限要素に対して実行される評価の無限シーケンスにつながります。 skipreduceはどちらも、 limit 操作を使用して無限ストリームを特定の要素数に制限しない限り、評価の実行から戻りません。

これは、無限のストリームを取得して最後の要素を取得しようとしたサンプルコードです。

Stream<Integer> stream = Stream.iterate(0, i -> i + 1);
stream.reduce((first, second) -> second).orElse(null);

その結果、ストリームは評価から戻らず、プログラムの実行を停止することになります

5. 結論

reduceSkip APIの両方を使用して、Streamの最後の要素を取得するさまざまな方法を見てきました。 また、これが無限のストリームでは不可能な理由についても調査しました。

Stream から最後の要素を取得することは、他のデータ構造から取得することと比較して簡単ではないことがわかりました。 これは、ターミナル関数が呼び出されない限り評価されない Streams の怠惰な性質のためであり、現在評価されている要素が最後の要素であるかどうかはわかりません。

コードスニペットはGitHubにあります。