Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/311.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/facebook/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 排序(数据流)按绝对大小加倍_Java_Java 8_Java Stream - Fatal编程技术网

Java 排序(数据流)按绝对大小加倍

Java 排序(数据流)按绝对大小加倍,java,java-8,java-stream,Java,Java 8,Java Stream,我有一系列的双值,我想求和得到最大值。 DoubleStream.summaryStatistics()听起来非常适合这样做。 getSum()方法有一个API注释,提醒我在我的一门计算机科学课程中学到了什么:如果按绝对值排序,求和问题的稳定性会更好。但是,DoubleStream不允许我指定要使用的比较器,如果我在流上调用sorted(),它将只使用Double.compareTo 因此,我将这些值收集到一个final Stream.Builder values=Stream.Builder(

我有一系列的双值,我想求和得到最大值。
DoubleStream.summaryStatistics()
听起来非常适合这样做。
getSum()
方法有一个API注释,提醒我在我的一门计算机科学课程中学到了什么:如果按绝对值排序,求和问题的稳定性会更好。但是,
DoubleStream
不允许我指定要使用的比较器,如果我在流上调用
sorted()
,它将只使用
Double.compareTo

因此,我将这些值收集到一个
final Stream.Builder values=Stream.Builder()和呼叫

values.build()
    .sorted(Comparator.comparingDouble(Math::abs))
    .mapToDouble(a -> a).summaryStatistics();
然而,这看起来有点冗长,我更愿意使用
DoubleStream.Builder
而不是通用的Builder。
我是否遗漏了什么,或者我真的必须使用流的装箱版本才能指定比较器?

对双流进行排序的唯一可能方法是装箱/取消装箱:

double[] input = //...
DoubleStream.of(input).boxed()
    .sorted(Comparator.comparingDouble(Math::abs))
    .mapToDouble(a -> a).summaryStatistics();

然而,由于内部使用Kahan求和,差异应该不是很显著。在大多数应用中,未分类的输入将产生良好的结果精度。当然,您应该自己测试未排序的求和是否适合您的特定任务。

原始流没有重载的
排序方法,将按照自然顺序进行排序。但是,回到您的根本问题,有一些方法可以提高总和的准确性,而不需要首先对数据进行排序

一个这样的算法是

无可否认,这是一个实现细节,因此通常的注意事项适用(非OpenJDK/Oracle JDK或未来的OpenJDK JDK可能采用其他方法等)


另请参阅本文:

您是否有一个通过使用外部API提供给您的
DoubleStream
,还是您自己构建的?我自己构建的。我也可以把它们放在双人床上。您的建议是只使用
sum
函数,让JDK来完成棘手的部分?这将意味着忽略API注释,并提出一个问题,即他们为什么首先将其放在那里。(为我的问题实现Kahan求和算法听起来像是重新发明轮子)@muued这就是我所做的,因为我知道(a)我的用户不使用替代的JDK,(b)我相当有信心OpenJDK将来不会转向“更糟糕”的算法。但是没有保证,所以这是你的决定,真的!如果您不习惯使用非文档化功能,您可以在自己的类中调整DoubleSummaryStatistics的代码(开源,但GPL2可能不适合您),并使用:
doubleStream.collect(YourStats::new,YourStats::accept,YourStats::combine)调用它