2017-05-04 13 views
2

次の例のようにsubstring(1)呼び出しを行うことなく、ストリームの要素を結合し、それぞれを "\ n"で区切って "\ n"で始まらないよりエレガントな方法はありますか?もちろんstream.reduceの後に先頭の文字を切り詰めるよりエレガントな方法はありますか?

List<String> strings = someList; 

    String rval = strings.stream() 
      .map(this::someOperation) 
      .reduce("", (p1, p2) -> p1 + "\n" + p2); 

    if(rval.length() > 0) 
    { 
     // trim off the leading "\n" 
     rval = rval.substring(1); 
    } 
    return rval; 
} 

それはあなたの問題を解決する使用

.collect(Collectors.joining("\n")) 

を私は内部ループでそれを置き換えることができますが、それは明らかに機能可読性

+4

それは単なる優雅さの問題ではありません。 '' ''はあなたのアキュムレータ関数のアイデンティティではないので、あなたのコードは '' reduce ''の契約に違反します。 '' + "\ n" + "a" 'は' 'a" 'と等しくありません。これを 'reduce'で正しく行うには、引数が1つのバージョン、' .reduce((a、b) - > a + "\ n" + b).orElse( "") 'を使うべきです。次に、 'substring'のステップが必要ないか、ストリームがパラレルの場合にランダムに表示される余分な" \ n "を持つリスクがあります。 https://docs.oracle.com/javase/8/docs/api/java/util/stream/Stream.html#reduce-T-java.util.function.BinaryOperator- – Misha

+0

を回答として追加してください。それをupvote、それは重要です –

答えて

5

文字列を効率的に処理する特定のコレクタがあります。 Collectors.joiningを見ると、それはあなたが探しているものであることがわかります:

String joined = strings.stream() 
    .map(this::someOperation) 
    .collect(Collectors.joining("\n")); 
+1

もう1つの答えを正しいものとしてマークしてください。それは私の前に掲載されました。 –

+1

彼らはお互いから1分以内に来てくれました。あなたの方がより完成していたので、もっと役に立つと思っていました。奇妙なことに、私はタイムスタンプをチェックして、あなたのことがとにかく最初だと思った –

6

を失うことになる、非常に読みやすく、かつまた、一時的な文字列やコピーをたくさん作成しないことで、より効率的です。

+1

ねえ、申し訳ありません、私の答えはあなたと同じです、と私はそれを後で投稿しました!私の言い訳:私は電話の上にいて、あなたが最初に答えたとは思わなかった。 –

+3

問題ありません。これは並行システムでは常に起こります。 –

関連する問題