As far as I know, the way to add a
List<Double> Using Java 8 streams it is this:
List<Double> 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<Double> vals = . . . ; double sum = vals.stream().reduce(0.0, (i,j) -> i+j);
reduce(....) is much longer than
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.max(). Going forward, I will definitely use this idiom for such operations on
List<Double> And similar.