2017-10-27 9 views
3

消費者を受け入れる中間機能であるストリーム上のピーク機能を持っています。それから、私の場合、なぜ「r」を「x」に置き換えないのでしょうか? peekは理想的にはデバッグ目的で使用する必要がありますが、なぜ私はここでうまくいかないのだろうかと思っていました。Javaでは、なぜストリームピークが私のために働いていないのですか?

List<String> genre = new ArrayList<String>(Arrays.asList("rock", "pop", "jazz", "reggae")); 
System.out.println(genre.stream().peek(s-> s.replace("r","x")).peek(s->System.out.println(s)).filter(s -> s.indexOf("x") == 0).count()); 
+1

Javaの文字列は不変です。 's.replace(" r "、" x ")'は、破棄される新しいStringを作成します。 –

答えて

5

peek()Consumerを受け入れるので。
Consumerは引数を受け入れるように設計されていますが、結果は返されません。ここで例えば

genre.stream().peek(s-> s.replace("r","x")) 

s.replace("r","x")が実際に行われているが、それはストリームの内容は変更されません。
peek()の呼び出し後にスコープ外にあるメソッドスコープのStringインスタンスです。

、あなたのテストを行いmap()によってpeek()を置き換えるために:

List<String> genre = new ArrayList<String>(Arrays.asList("rock", "pop", "jazz", "reggae")); 
System.out.println(genre.stream().map(s -> s.replace("r", "x")) 
           .peek(s -> System.out.println(s)) 
           .filter(s -> s.indexOf("x") == 0).count()); 
1

のはあなたがストリームの結果を印刷したり、ログインするためにはforEachを使用することができ、ストリームでの操作のパイプラインをデバッグしようとしているとしましょう。

ストリーム操作のピークが役立つところです。ストリームの目的は、ストリームの各要素が消費されるたびにアクションを実行することです。 しかし、それはforEachのようにストリーム全体を消費しません。アクションを実行した要素をパイプラインの次の操作に転送します。

あなたの場合は、このようにしてください。

List<String> genre = new ArrayList<String>(Arrays.asList("rock", "pop", 
"jazz","reggae")); 
    genre.stream() 
     .peek(s -> System.out.println("from stream:" + s)) 
     .map(x -> x.replace("r", "x")) 
     .peek(s -> System.out.println("from replace stream:" + s)) 
     .filter(y -> y.indexOf("y") == 0) 
     .peek(s -> System.out.println("from stream:" + s)) 
     .collect(toList());