Ответ 1
Я бы пошел на такой подход:
private static Optional<Double> convert(OptionalDouble od)
{
return od.isPresent() ?
Optional.of(od.getAsDouble()) : Optional.empty();
}
У меня есть метод, который создает список, и я хочу, чтобы он возвращал среднее значение списка как необязательное значение.
Однако, когда я вычисляю среднее значение с использованием Java 8, я всегда получаю возвращаемое значение как необязательный.
Как преобразовать
OptionalDouble to Optional<Double>?
Ниже приведен мой код для среднего расчета:
private static Optional<Double> averageListValue() {
// Build list
List<Double> testList = new ArrayList<>();
testList.add(...);
...
...
return testList.stream().mapToDouble(value -> value).average();
}
Спасибо.
Я бы пошел на такой подход:
private static Optional<Double> convert(OptionalDouble od)
{
return od.isPresent() ?
Optional.of(od.getAsDouble()) : Optional.empty();
}
Кстати, я нашел другое решение, которое имеет самую простую форму.
Я начал думать: когда результат среднего может быть пустым? Только когда список его сам пуст, не так ли? Поэтому, если мы уверены, что список не пуст, мы можем безопасно выполнить getAsDouble()
:
return Optional.ofNullable(testList.isEmpty() ? null :
testList.stream().mapToDouble(v -> v).average().getAsDouble())
(с точки зрения производительности это может быть более эффективным, чем создание дополнительных лямбда-оберток, что было предложено в похожих ответах.)
Небольшое отклонение от @Andremoniy answer заключается в пропуске DoubleStream
и использовании коллектора averagingDouble()
:
if (testList.isEmpty()) {
return Optional.empty();
}
return Optional.of(testList.stream().collect(Collector.averagingDouble()));
Или рассмотрите, является ли 0 допустимым возвращаемым значением для пустого списка и, возможно, полностью пропустите Optional
.
Я не знаю, существует ли опрятное решение, но он должен работать:
OptionalDouble optionalDouble = testList.stream().mapToDouble(value -> value).average();
return Optional.ofNullable(optionalDouble.isPresent() ? optionalDouble.getAsDouble() : null);
Просто для удовольствия, я хотел посмотреть, может ли он быть написан в одном заявлении, без какой-либо дополнительной переменной tempDouble. Вот лучшее, что я придумал:
return testList.stream().collect(Collectors.collectingAndThen(
Collectors.summarizingDouble(Double::doubleValue),
stat -> Optional.ofNullable(stat.getCount()>0 ? stat.getAverage() : null)));
Я пришел к решению "одна строка" (одно выражение):
return ((Function<OptionalDouble, Optional<Double>>) od
-> od.isPresent() ? Optional.of(od.getAsDouble()) : Optional.empty())
.apply(testList.stream().mapToDouble(v -> v).average());
Кстати, только ради минимализма, если вы сделаете статический импорт:
import static java.util.Optional.*;
вы можете опустить Optional.
, что делает его немного менее грязным.