我有一个构建列表的方法,我希望它将列表的平均值作为可选值返回。
但是,当我使用Java 8计算平均值时,我总是将返回值作为OptionalDouble。
如何转换
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();
}
感谢。
答案 0 :(得分:7)
我采用这种方法:
private static Optional<Double> convert(OptionalDouble od)
{
return od.isPresent() ?
Optional.of(od.getAsDouble()) : Optional.empty();
}
答案 1 :(得分:4)
BTW,我找到了另一个解决方案,它的形式最简单。
我开始考虑:平均结果可能是空的吗?只有列出它自己是空的,对吧?因此,如果我们确定列表不是空的,那么我们可以安全地执行getAsDouble()
:
return Optional.ofNullable(testList.isEmpty() ? null :
testList.stream().mapToDouble(v -> v).average().getAsDouble())
(从性能的角度来看,这可能比创建额外的lambda包装更有效,正如在类似的答案中所建议的那样。)
答案 2 :(得分:4)
@Andremoniy's answer略有不同,就是跳过DoubleStream
并使用averagingDouble()
收集器:
if (testList.isEmpty()) {
return Optional.empty();
}
return Optional.of(testList.stream().collect(Collector.averagingDouble()));
或者考虑0是否是空列表的有效返回值,并且可能完全跳过Optional
。
答案 3 :(得分:2)
这是一个很老的问题,但是在Java的较新版本中,您可以:
// Given an OptionalDouble
var myOptionalDouble = OptionalDouble.of(3.0d);
// Convert to Optional<Double>
var myOptional = myOptionalDouble.stream().boxed().findFirst();
反向操作同样容易:
var myOptional = Optional.of(Double.valueOf(3.0d));
var myOptionalDouble = myOptional.stream().mapToDouble(t -> t).findFirst();
答案 4 :(得分:1)
我不知道是否存在一个简洁的解决方案,但这应该有效:
OptionalDouble optionalDouble = testList.stream().mapToDouble(value -> value).average();
return Optional.ofNullable(optionalDouble.isPresent() ? optionalDouble.getAsDouble() : null);
答案 5 :(得分:1)
只是为了好玩,我想看看它是否可以写在一个语句中,而不需要一个OptionalDouble临时变量。这是我提出的最好的:
return testList.stream().collect(Collectors.collectingAndThen(
Collectors.summarizingDouble(Double::doubleValue),
stat -> Optional.ofNullable(stat.getCount()>0 ? stat.getAverage() : null)));
答案 6 :(得分:1)
我来到这个“一线”(单一陈述)解决方案:
return ((Function<OptionalDouble, Optional<Double>>) od
-> od.isPresent() ? Optional.of(od.getAsDouble()) : Optional.empty())
.apply(testList.stream().mapToDouble(v -> v).average());
BTW,只是为了极简主义,如果你要进行静态导入:
import static java.util.Optional.*;
你可以省略Optional.
,这会让它变得不那么混乱。