将OptionalDouble转换为可选<;java.lang.Double>;

将OptionalDouble转换为可选<;java.lang.Double>;,java,java-8,average,optional,Java,Java 8,Average,Optional,我有一个构建列表的方法,我希望它将列表的平均值作为可选值返回 然而,当我使用Java8计算平均值时,我总是以OptionalDouble的形式得到返回值 我如何转换 OptionalDouble to Optional<Double>? OptionalDouble到Optional? 以下是我的平均计算代码: private static Optional<Double> averageListValue() { // Build list Li

我有一个构建列表的方法,我希望它将列表的平均值作为可选值返回

然而,当我使用Java8计算平均值时,我总是以OptionalDouble的形式得到返回值

我如何转换

OptionalDouble to Optional<Double>?
OptionalDouble到Optional?
以下是我的平均计算代码:

private static Optional<Double> averageListValue() {
     // Build list
     List<Double> testList = new ArrayList<>();
     testList.add(...);
     ...
     ...


     return testList.stream().mapToDouble(value -> value).average();
}
private静态可选averageListValue(){
//构建列表
List testList=new ArrayList();
添加(…);
...
...
返回testList.stream().mapToDouble(value->value.average();
}

谢谢。

我不知道是否有一个好的解决方案,但应该可以:

OptionalDouble optionalDouble = testList.stream().mapToDouble(value -> value).average();
return Optional.ofNullable(optionalDouble.isPresent() ? optionalDouble.getAsDouble() : null);

只是为了好玩,我想看看它是否可以写在一个语句中,而不需要任何OptionalDouble临时变量。以下是我想到的最好的:

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());

您可以省略
可选项。
,这会使它稍微不那么凌乱。

我选择这种方法:

private static Optional<Double> convert(OptionalDouble od) {
    return od.isPresent() ? 
        Optional.of(od.getAsDouble()) : Optional.empty();
}
私有静态可选转换(可选双od){
返回od.isPresent()?
Optional.of(od.getAsDouble()):Optional.empty();
}

顺便说一句,我找到了另一种解决方案,它的形式最简单

我开始思考:平均值的结果何时可以为空?只有当列表本身为空时,对吗?所以,如果我们确定列表不是空的,那么我们就可以安全地执行
getAsDouble()

(从性能的角度来看,这可能比创建额外的lambda包装器更有效,正如在类似的回答中所建议的那样。)

的一个细微变化是跳过
双流
并使用
averagingDouble()
收集器:

if (testList.isEmpty()) {
    return Optional.empty();
}
return Optional.of(testList.stream().collect(Collector.averagingDouble()));

或考虑0是否是空列表的有效返回值,并且可能完全跳过<代码>可选< />代码>

这是一个相当古老的问题,但是在新版本的java中,您可以:

//给定一个OptionalDouble
var myOptionalDouble=OptionalDouble.of(3.0d);
//转换为可选
var myOptional=myoptionalduble.stream().boxed().findFirst();
反之亦然:

var myOptional=Optional.of(Double.valueOf(3.0d));
var myoptionalduble=myOptional.stream().mapToDouble(t->t.findFirst();

OptionalDouble上的
getAsDouble
如何,这将得到您最终想要的
double
中的平均值。OptionalDouble更有效;更接近于
double
,因此将使用代码从
Optional
转换为
optionalduble
似乎更好。但是,我想你知道这一点,并且有你的理由。如果代码构建了一个如图所示的列表,你已经知道它永远不会是空的。那么为什么要返回一个
可选的
。显然,这种方法在这里也达成了共识。@JoopEggen感谢您提供的信息。是的,我有我的理由…这是一个双重测试,首先是
isEmpty()
,然后是
null
中的
测试。不需要第二个测试:
returntestlist.isEmpty()?Optional.empty():Optional.of(testList.stream().mapToDouble(v->v.average().getAsDouble())
我考虑过,但我特别在
Optional.of nullable
中加入了三元操作。它更时尚,但我同意它还有一个比较操作
return Optional.ofNullable(testList.isEmpty() ? null : 
        testList.stream().mapToDouble(v -> v).average().getAsDouble())
if (testList.isEmpty()) {
    return Optional.empty();
}
return Optional.of(testList.stream().collect(Collector.averagingDouble()));