31

foldLeftJava 8 におけるScala の優れた機能に相当するものは何ですか?

だと思いたくなりましたがreduce、reduce は、reduce したものと同じ型のものを返さなければなりません。

例:

import java.util.List;

public class Foo {

    // this method works pretty well
    public int sum(List<Integer> numbers) {
        return numbers.stream()
                      .reduce(0, (acc, n) -> (acc + n));
    }

    // this method makes the file not compile
    public String concatenate(List<Character> chars) {
        return chars.stream()
                    .reduce(new StringBuilder(""), (acc, c) -> acc.append(c)).toString();
    }
}

上記のコードの問題は、accumulator です。new StringBuilder("")

foldLeftしたがって、誰かが/fix my codeに相当する適切なものを教えてもらえますか?

4

5 に答える 5

18

アップデート:

コードを修正するための最初の試みは次のとおりです。

public static String concatenate(List<Character> chars) {
        return chars
                .stream()
                .reduce(new StringBuilder(),
                                StringBuilder::append,
                                StringBuilder::append).toString();
    }

次のreduce メソッドを使用します。

<U> U reduce(U identity,
                 BiFunction<U, ? super T, U> accumulator,
                 BinaryOperator<U> combiner);

紛らわしいかもしれませんが、javadocs を見ると、詳細をすばやく把握するのに役立つ優れた説明があります。リダクションは、次のコードと同等です。

U result = identity;
for (T element : this stream)
     result = accumulator.apply(result, element)
return result;

より詳細な説明については、このソースを確認してください。

ただし、この使用法は正しくありません。アキュムレータは、追加の要素を result に組み込むための連想的で、干渉しない、ステートレスな関数でなければならないという reduce の規約に違反しているためです。つまり、ID は変更可能であるため、並列実行の場合、結果は壊れます。

以下のコメントで指摘されているように、正しいオプションは次のように削減を使用しています。

return chars.stream().collect(
     StringBuilder::new, 
     StringBuilder::append, 
     StringBuilder::append).toString();

サプライヤーStringBuilder::newは、後で結合される再利用可能なコンテナーを作成するために使用されます。

于 2016-12-20T10:55:11.757 に答える