在 java 8 中从整数数组减少到两倍

Reduce from array of integers to double in java 8

这是我的代码:

// assuming HashMap<String, Integer> hashmap
double sum = hashmap.values().stream()
    .reduce(.0, (i, v) -> i + Math.pow(v,2) + 0.5 );

在这种情况下,reduce 应该取 (Integer i) 和 (double v) 并对它们求和,return 这个 reduce 是一个 double。

相反,我得到了这个错误:

- The method reduce(Integer, BinaryOperator<Integer>) in the type Stream<Integer> is not applicable for the arguments (double, (<no type> i, <no type> v) -> {})

- Type mismatch: cannot convert from double to Integer

减少,

但是,这修复了:

// assuming HashMap<String, Integer> hashmap
double sum = hashmap.values().stream()
    .map((t)->(double)t)
    .reduce(.0, (i, v) -> i + Math.pow(v,2) + 0.5 );

有没有更优雅的方法?

A BinaryOperator 必须接受两个相同类型的参数。但是,您肯定想使用

double sum = hashmap.values().stream().mapToDouble(Integer::doubleValue)
  .reduce(.0, (i, v) -> i + Math.pow(v,2) + 0.5 );

以避免不必要的装箱转换 Stream.mapToDouble(…) converts the Stream to a DoubleStream。相反,在 Stream 上调用 .map((t)->(double)t) 将创建 Double 个实例到 Integer 个实例。


但请注意,您对 reduce 的使用违反了其合同。第一个参数(您在这里使用 0.)必须是缩减函数的标识值。 “标识值”意味着对于任何值 vapply(identity, v) 必须导致 v,这里不是这种情况。不符合身份契约

您只是想对 v * v + 0.5 的值求和吗?

如果是这样,最清晰的解决方案是

double sum = 0;
for (int v : hashmap.values())
    sum += v * v + 0.5;

如果你必须使用流,答案是

double sum = hashmap.values().stream().mapToDouble((v) -> v * v + 0.5).sum();

但是尝试使用 reduce() 这样做是没有意义的,因为 0.0 不是累加器的标识并且累加器不是关联的。