如何使用流对Map中的值求和?

Jay*_*Jay 37 java generics java-8 java-stream

我想要一个与流相当的:

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;
}
Run Code Online (Sandbox Code Playgroud)

这段代码实际上并没有编译,因为0不能分配给类型T,但你明白了.

Pau*_*ton 67

你可以这样做:

int sum = data.values().stream().mapToInt(Integer::parseInt).sum();
Run Code Online (Sandbox Code Playgroud)

  • @Jay请参阅此答案,了解如何对流进行缩减以获得广义总和:http://stackoverflow.com/a/30019328/3973077 (3认同)
  • @Jay你可以传递映射器和夏天.你最终会得到类似`MyMath.sum(map,Number :: intValue,Integer :: sum)`的东西,而summer是一个reduce操作.那不是更好,所以不是真的. (2认同)
  • 您需要做的是在我链接的问题中创建一个"Summable"接口,然后让类为每个数字类型实现该接口(`WrappedInt`,`WrappedDouble`等). (2认同)

Rad*_*def 13

这是另一种方法:

int sum = data.values().stream().reduce(0, Integer::sum);
Run Code Online (Sandbox Code Playgroud)

(int然而,对于一个总和而言,保罗的回答减少了拳击和拆箱.)

至于这样做的一般,我不认为有这更方便的方式.

我们可以这样做:

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

int sum = MyMath.sum(data, Integer::sum);
Run Code Online (Sandbox Code Playgroud)

但是你总是度过夏天.reduce也有问题,因为它返回Optional.上面的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);
Run Code Online (Sandbox Code Playgroud)


小智 5

Integer sum = intMap.values().stream().mapToInt(d-> d).sum();
Run Code Online (Sandbox Code Playgroud)

使用以聚合 sum 方法结尾的 lambda 表达式获取HashMap.valuesStream 和 Collect 的方法。mapToIn