【问题标题】:Reducing ArrayList with Math.log on all elements在所有元素上使用 Math.log 减少 ArrayList
【发布时间】:2022-12-01 00:07:12
【问题描述】:

我有一个浮点数组列表,我想对数组中的所有元素使用 Math.log 方法,然后将它们相加。是这样的:

var doubleValue = floatArrayList.stream()
        .reduce( 1.0, (a, b) -> Math.log(a) + Math.log(b));

我的结果是doubleValue == NaN

我在这里做错了什么?

【问题讨论】:

  • 你的清单上有什么?只是零元素?
  • 一个问题...假设您有一个包含三个元素abc 的列表。您目前正在计算log(c) + log(log(b) + log(log(a) + log(1)))...或类似的东西,因为您正在重复计算总和的日志。我怀疑这是你想要的。
  • 你为什么不先map()Math.log()的值然后求和呢?类似于 floatArrayList.stream().mapToDouble(Math::log).sum() - 可能比 reduce(0.0, (sum, value) -> sum + Math.log(value)) 更容易阅读和使用。
  • 考虑(更好的命名):reduce(subtotal, (subtotal, x) -> ...),然后(应用于您的用例)更好:reduce(0f, (subtotal, x) -> subtotal + Math.log(x));)
  • 通过 Math.log() 折叠流元素时,在某些时候对数变为零,我猜零的对数将被解析为负无穷大.然后尝试计算Math.log(Double.NEGATIVE_INFINITY),看看你会得到什么。

标签: java java-stream


【解决方案1】:

这可能是你想要做的。

List<Double> doubles = List.of(1.,3.,2.4,5.7,10.);
double d1 = Math.log(doubles.stream().skip(1).reduce(1.0, (a,b)->a*b));
double d2 = doubles.stream().reduce(Math.log(1.0), (a,b)-> a + Math.log(b));

System.out.println(d1);
System.out.println(d2);

印刷

6.01713229385656
6.017132293856561

根据您的值的大小,从 log(a) + log(b) = log(a*b) 开始,与重复调用 Math.log 方法相比,第一种方法可能更有效。

【讨论】:

    猜你喜欢
    • 2015-04-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-24
    • 2013-04-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多