Java 8 Streams peek()API

1. 前書き

link:/java-8-streams[Java Stream API]は、データを処理するための強力な代替手段を紹介します。
この短いチュートリアルでは、誤解されることが多いメソッドである_peek()_に焦点を当てます。

2. 簡単な例

手を汚して_peek()_を使用してみましょう。 名前のストリームがあり、それらをコンソールに出力したい。
_peek()_は唯一の引数として_Consumer <T> _を想定しているため、適切なように思えるので、試してみましょう。
Stream<String> nameStream = Stream.of("Alice", "Bob", "Chuck");
nameStream.peek(System.out::println);
ただし、上記のスニペットは出力を生成しません。 その理由を理解するために、ストリームのライフサイクルの側面について簡単に復習しましょう。

3. 中級vs. ターミナル運営

ストリームには3つの部分があることを思い出してください。データソース、ゼロ以上の中間操作、およびゼロまたは1つの端末操作です。
ソースは、パイプラインに要素を提供します。
中間操作では、要素を1つずつ取得して処理します。 *すべての中間操作は遅延であり、その結果、パイプラインが機能し始めるまで操作は効果がありません。*
端末操作は、ストリームのライフサイクルの終了を意味します。 私たちのシナリオで最も重要なのは、彼らがパイプラインで作業を開始することです*。

4. _peek()_使用法

最初の例で_peek()_が機能しなかった理由は、それが_intermediate_操作であり、_terminal_操作*をパイプラインに適用しなかったためです。 または、同じ引数で_forEach()_を使用して、目的の動作を取得することもできます。
Stream<String> nameStream = Stream.of("Alice", "Bob", "Chuck");
nameStream.forEach(System.out::println);
_peek()_のhttps://docs.oracle.com/javase/8/docs/api/java/util/stream/Stream.html#peek-java.util.function.Consumer-[Javadocページ]は次のように述べています。 「*このメソッドは、主にデバッグをサポートするために存在します。ここでは、パイプライン内の特定のポイントを通過するエレメントを表示します*」。
同じJavadocページからこのスニペットを考えてみましょう。
Stream.of("one", "two", "three", "four")
  .filter(e -> e.length() > 3)
  .peek(e -> System.out.println("Filtered value: " + e))
  .map(String::toUpperCase)
  .peek(e -> System.out.println("Mapped value: " + e))
  .collect(Collectors.toList());
各操作に合格した要素をどのように観察するかを示しています。
それに加えて、_peek()_は別のシナリオで役立ちます:*要素の内部状態を変更したいとき*。 たとえば、印刷する前にすべてのユーザーの名前を小文字に変換するとします。
Stream<User> userStream = Stream.of(new User("Alice"), new User("Bob"), new User("Chuck"));
userStream.peek(u -> u.setName(u.getName().toLowerCase()))
  .forEach(System.out::println);
あるいは、_map()_を使用することもできますが、要素を置き換えたくないので、_peek()_の方が便利です。

5. 結論

この短いチュートリアルでは、_peek()_の仕組みを理解するために、ストリームのライフサイクルの概要を見ました。 また、_peek()_を使用することが最も簡単なオプションである場合の2つの日常的なユースケースも確認しました。
そしていつものように、例はhttps://github.com/eugenp/tutorials/tree/master/java-streams[GitHub上]で入手できます。