Насколько я могу судить, способ суммирования List<Double> с использованием потоков Java 8:
List<Double> vals = . . . ;
double sum = vals.stream().mapToDouble(Double::doubleValue).sum();
Мне кажется, что mapToDouble(Double::doubleValue) кажется крутым - это просто церемониальная церемония, которую лямбды и ручьи должны были обойтись без.
Лучшие практики говорят нам, что мы предпочитаем экземпляры List для массивов, и все же для такого рода суммирования массивы кажутся более чистыми:
double[] vals = . . . ;
double sum = Arrays.stream(vals).sum();
Конечно, это можно сделать:
List<Double> vals = . . . ;
double sum = vals.stream().reduce(0.0, (i,j) -> i+j);
Но это reduce(....) намного длиннее sum().
Я понимаю, что это связано с тем, как потоки необходимо модифицировать вокруг Java-объектов, не являющихся объектами, но все-таки я что-то упустил? Есть ли способ сжать автобоксинг, чтобы сделать это короче? Или это только текущее состояние искусства?
Обновление - дайджест ответов
Ниже приведен дайджест ответов. В то время как у меня есть резюме здесь, я настоятельно призываю читателя полностью ознакомиться с ответами.
@dasblinkenlight объясняет, что какой-то unboxing всегда будет необходим из-за решений, принятых еще в истории Java, в частности, в том, как были реализованы дженерики и их связь с неэлементными примитивами. Он замечает, что теоретически возможно, чтобы компилятор смог выполнить unboxing и разрешить более короткий код, но это еще не реализовано.
@Holger показывает решение, которое очень близко к выразительности, о которой я спрашивал:
double sum = vals.stream().reduce(0.0, Double::sum);
Я не знал о новом статическом методе Double.sum(). Добавленный с 1.8, кажется, предназначен для самой цели, которую я описывал. Я также нашел Double.min() и Double.max(). В будущем я обязательно буду использовать эту идиому для таких операций на List<Double> и т.д.