Подтвердить что ты не робот

Как суммировать значения на карте с потоком?

Я хочу эквивалент этого с потоком:

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, но вы получаете идею.

4b9b3361

Ответ 1

Вы можете сделать это:

int sum = data.values().stream().mapToInt(Number::intValue).sum();

Ответ 2

Здесь другой путь, который немного короче:

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

Я думал об этом, и я действительно не вижу способа сделать его общим, что на самом деле более удобно, чем идеи здесь.

Мы могли бы сделать что-то вроде этого:

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

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

Но вы всегда заканчиваете лето, а reduce также проблематично, потому что он возвращает Optional. (Вышеуказанный метод sum создает исключение для пустой карты, но пустая сумма должна быть 0.)

Ответ 3

Вы можете сделать это следующим образом:

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