Ответ Равиндры предоставляет правильное решение, но чтобы понять, почему ваше решение не работает, рассмотрите следующие:
Double totalSalary = empList.stream().parallel()
.filter(x -> x.getName().equalsIgnoreCase("XYZ"))
// crucial aspect of mapping to the type that you want to reduce
.map(Employee::getSalary)
// reduction as a stage of stream pipeline execution
.reduce(0, // identity element for sum, but with a flaw!!
(subTotal, sal) -> Double.sum(subTotal, sal), // accumulator to sum double values
Double::sum // the combiner function compatible with accumulation
);
Причина, по которой идентичность ошибочна, заключается в том, чтоиз-за 0 тип subTotal
в аккумуляторе не будет выводиться как double
, как ожидается методом Double#sum
. Следовательно, обновление кода далее с использованием Double.NaN
заставит его работать следующим образом:
Double totalSalary = empList.stream().parallel()
.filter(x -> x.getName().equalsIgnoreCase("XYZ"))
.map(Employee::getSalary)
.reduce(Double.NaN, Double::sum, Double::sum); // identity element and method reference for accumulator
Хотя обратите внимание, это может быть просто представлено с исключением объединителя в этом случае как:
Double totalSalary = empList.stream().parallel()
.filter(x -> x.getName().equalsIgnoreCase("XYZ"))
.map(Employee::getSalary)
.reduce(Double.NaN, Double::sum);
и поскольку sum
в конечном итоге является операцией примитивных типов , было бы очень удобно использовать отображение DoubleStream
, которое является примитивной специализацией потока для элементов с двойным значением.