As far as I know, the way to add a List
Using Java 8 streams it is this:
List vals = . . . ;
double sum = vals.stream().mapToDouble(Double::doubleValue).sum();
For me, the mapToDouble(Double::doubleValue)
looks like some kind of crufty – just the kind of warming “ceremony” that lambdas and brooks were supposed to give up on.
Best practices tell us to prefer List
instances with respect to matrices, yet for this type of sum, the matrices look cleaner:
double[] vals = . . . ;
double sum = Arrays.stream(vals).sum();
Granted, you could do this:
List vals = . . . ;
double sum = vals.stream().reduce(0.0, (i,j) -> i+j);
But what reduce(....)
is much longer than sum()
.
I understand this has to do with how streams need to be adapted to Java’s non-object primitives, but am I still missing something here? Is there a way to squeeze autoboxing to make this shorter? Or is it just the current state of the art?
Update – Digest Answers
Here is a summary of the answers below. While I have a summary here, I urge the reader to read the answers in full.
@dasblinkenlight explains that some kind of unboxing will always be required, due to decisions made further back in Java history, particularly in how generics were implemented and their relationship to non-objective primitives. Note that it is theoretically possible for the compiler to guess unboxing and allow shorter code, but this has not yet been implemented.
@Holger shows a solution very close to the expressiveness I was wondering about:
double sum = vals.stream().reduce(0.0, Double::sum);
I was not aware of the new static method Double.sum()
. Added with 1.8, it seems intended for the very purpose I was describing. I also found Double.min()
And Double.max()
. Going forward, I will definitely use this idiom for such operations on List
And similar.