I have a series of double values which I want to sum up and get the maximum value.
The DoubleStream.summaryStatistics()
sounds perfect for that.
The getSum()
method has an API note reminding me of what I learned during one of my computer science courses: the stability of the summation problem tends to be better if the values are sorted by their absolute values. However, DoubleStream
does not let me specify the comparator to use, it will just use Double.compareTo
if I call sorted()
on the stream.
Thus I gathered the values into a final Stream.Builder<Double> values = Stream.builder();
and call
values.build()
.sorted(Comparator.comparingDouble(Math::abs))
.mapToDouble(a -> a).summaryStatistics();
Yet, this looks somewhat lengthy and I would have preferred to use the DoubleStream.Builder
instead of the generic builder.
Did I miss something or do I really have to use the boxed version of the stream just to be able to specify the comparator?
Java Stream sorted() Learn to use Stream sorted() method to sort the elements in a Stream by their natural order.
Given an array of integers arr , write a function absSort(arr) , that sorts the array according to the absolute values of the numbers in arr . If two numbers have the same absolute value, sort them according to sign, where the negative numbers come before the positive numbers. Constraints: [time limit] 5000ms.
Sorting a List of Integers with Stream. Found within the Stream interface, the sorted() method has two overloaded variations that we'll be looking into. This methods returns a stream consisting of the elements of the stream, sorted according to natural order - the ordering provided by the JVM.
The java. util. Arrays. sort(double[]) method sorts the specified array of doubles into ascending numerical order.
Primitive streams don't have an overloaded sorted
method and will get sorted in natural order. But to go back to your underlying problem, there are ways to improve the accuracy of the sum that don't involve sorting the data first.
One such algorithm is the Kahan summation algorithm which happens to be used by the OpenJDK/Oracle JDK internally.
This is admittedly an implementation detail so the usual caveats apply (non-OpenJDK/Oracle JDKs or future OpenJDK JDKs may take alternative approaches etc.)
See also this post: In which order should floats be added to get the most precise result?
The only possible way to sort DoubleStream
is to box/unbox it:
double[] input = //...
DoubleStream.of(input).boxed()
.sorted(Comparator.comparingDouble(Math::abs))
.mapToDouble(a -> a).summaryStatistics();
However as Kahan summation is used internally, the difference should be not very significant. In most of applications unsorted input will yield the good resulting accuracy. Of course you should test by yourself if the unsorted summation is satisfactory for your particular task.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With