简体   繁体   English

将 OptionalDouble 转换为 Optional<java.lang.Double>

[英]Convert OptionalDouble to Optional <java.lang.Double>

I have a method that builds a list and I want it to return the average of the list as an Optional value.我有一个构建列表的方法,我希望它返回列表的平均值作为 Optional 值。

However, when I calculate the average value using Java 8, I always get the return value as an OptionalDouble.但是,当我使用 Java 8 计算平均值时,我总是将返回值作为 OptionalDouble。

How do I convert我如何转换

OptionalDouble to Optional<Double>?

Below are my code for average calculation:以下是我的平均计算代码:

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


     return testList.stream().mapToDouble(value -> value).average();
}

Thanks.谢谢。

I'd go for this approach:我会采用这种方法:

private static Optional<Double> convert(OptionalDouble od) {
    return od.isPresent() ? 
        Optional.of(od.getAsDouble()) : Optional.empty();
}

A slight variation on @Andremoniy's answer is to skip the DoubleStream and use the averagingDouble() collector: @Andremoniy 的答案略有不同是跳过DoubleStream并使用averagingDouble()收集器:

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

Or consider whether 0 is a valid return value for an empty list, and possibly skip the Optional entirely.或者考虑 0 是否是空列表的有效返回值,并可能完全跳过Optional

BTW, I found another solution, which has most simple form.顺便说一句,我找到了另一个解决方案,它具有最简单的形式。

I've started thinking about: when result of average can be empty?我开始思考:什么时候平均的结果可以为空? Only when list it self is empty, right?只有当列表自身为空时,对吗? So if we are sure that list is not empty, than we can safely do getAsDouble() :因此,如果我们确定列表不为空,那么我们可以安全地执行getAsDouble()

return Optional.ofNullable(testList.isEmpty() ? null : 
        testList.stream().mapToDouble(v -> v).average().getAsDouble())

(from performance point of view this could be more efficient than creating additional lambda wrappers, as was suggested in similar answers.) (从性能的角度来看,这可能比创建额外的 lambda 包装器更有效,正如类似答案中所建议的那样。)

This is quite an old question, but in newer versions of Java you can:这是一个很老的问题,但在较新版本的 Java 中,您可以:

// Given an OptionalDouble
var myOptionalDouble = OptionalDouble.of(3.0d);

// Convert to Optional<Double>
var myOptional = myOptionalDouble.stream().boxed().findFirst();

The reverse is similarly easy:反过来也同样简单:

var myOptional = Optional.of(Double.valueOf(3.0d));

var myOptionalDouble = myOptional.stream().mapToDouble(t -> t).findFirst();

I don't know if there exists a neat solution, but ths should work:我不知道是否存在一个简洁的解决方案,但是这应该有效:

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

Just for fun, I wanted to see if it could be written in a single statement, without any need for an OptionalDouble temp variable.只是为了好玩,我想看看它是否可以写在单个语句中,而无需 OptionalDouble 临时变量。 Here is the best I came up with:这是我想出的最好的:

return testList.stream().collect(Collectors.collectingAndThen(
    Collectors.summarizingDouble(Double::doubleValue),
    stat -> Optional.ofNullable(stat.getCount()>0 ? stat.getAverage() : null)));

I came to this "one line" (single statement) solution:我来到了这个“一行”(单语句)解决方案:

    return ((Function<OptionalDouble, Optional<Double>>) od
            -> od.isPresent() ? Optional.of(od.getAsDouble()) : Optional.empty())
            .apply(testList.stream().mapToDouble(v -> v).average());

BTW, just for sake of minimalism, if you will do static import:顺便说一句,为了极简主义,如果您要进行静态导入:

import static java.util.Optional.*;

you can omit Optional.你可以省略Optional. , what makes it a little bit less messy. ,是什么让它不那么凌乱。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM