web-dev-qa-db-ja.com

ストリームを使用してマップの値を合計する方法は?

ストリームでこれと同等のものが欲しい:

public static <T extends Number> T getSum(final Map<String, T> data) {
    T sum = 0;
    for (String key: data.keySet())
        sum += data.get(key);
    return sum;
}

0をT型に割り当てることができないため、このコードは実際にはコンパイルされませんが、アイデアは得られます。

32
Jay

あなたはこれを行うことができます:

int sum = data.values().stream().mapToInt(Integer::parseInt).sum();
63
Paul Boddington

これを行う別の方法を次に示します。

int sum = data.values().stream().reduce(0, Integer::sum);

(ただし、intだけの合計では、Paulの答えはボクシングとアンボクシングを減らします。)

これを行うことに関して一般的に、私ははるかに便利な方法があるとは思わない。

次のようなことができます。

static <T> T sum(Map<?, T> m, BinaryOperator<T> summer) {
    return m.values().stream().reduce(summer).get();
}

int sum = MyMath.sum(data, Integer::sum);

しかし、あなたはいつも夏を過ぎてしまいます。 reduceOptionalを返すため問題があります。上記のsumメソッドは、空のマップに対して例外をスローしますが、空の合計は0でなければなりません。もちろん、0も渡すことができます。

static <T> T sum(Map<?, T> m, T identity, BinaryOperator<T> summer) {
    return m.values().stream().reduce(identity, summer);
}

int sum = MyMath.sum(data, 0, Integer::sum);
12
Radiodef

次のようにできます:

int creditAmountSum = result.stream().map(e -> e.getCreditAmount()).reduce(0, (x, y) -> x + y);
1
Saeed Zarinfam