Java 如何将可选项映射到基本可选项?

Java 如何将可选项映射到基本可选项?,java,lambda,optional,Java,Lambda,Optional,我知道我可以将一个Optional映射到另一个包装器类型Optional Optional<Long> millis(Date date) { return ofNullable(date).map(Date::getTime); } 我试过了,但运气不好 ofNullable(value).flatMap(v -> { // javac has never liked me return OptionalLong.of(v.getTime()); });

我知道我可以将一个
Optional
映射到另一个包装器类型Optional

Optional<Long> millis(Date date) {
    return ofNullable(date).map(Date::getTime);
}
我试过了,但运气不好

ofNullable(value).flatMap(v -> { // javac has never liked me
    return OptionalLong.of(v.getTime());
});

您可以使用
map
获取一个
可选的
,然后
orElse
删除外部
可选的
,如下所示:

OptionalLong millis(Date date) {
    return Optional.ofNullable(date).map(Date::getTime)
            .map(OptionalLong::of).orElse(OptionalLong.empty());
}
另一种(本例中较短)方法是使用三元运算符:

OptionalLong millis(Date date) {
    return date == null ? OptionalLong.empty() : OptionalLong.of(date.getTime());
}
或者如果您已经有了可选的

OptionalLong到OptionalLong(可选o){
返回o.map(OptionalLong::of).orElse(OptionalLong.empty());
}
可选长到可选长(可选o){
返回o.isPresent()?OptionalLong.of(o.get()):OptionalLong.empty();
}
使用

可选长毫秒(最终日期){
返回StreamEx.ofNullable(date).mapToLong(date::getTime).findAny();
}

可选长托龙(可选o){
返回streamx.of(o).mapToLong(Long::longValue).findAny();
}

可选长托龙(最终可选o){
返回StreamEx.of(o).mapToLong(日期::getTime.findAny();
}

我将按如下方式实现它:

OptionalLong toOptionalLong(Optional<Long> optionalValue) {
    return optionalValue.map(OptionalLong::of).orElseGet(OptionalLong::empty);
}
OptionalLong到OptionalLong(可选optionalValue){
返回optionalValue.map(OptionalLong::of).orelsGet(OptionalLong::empty);
}
当且仅当
optionalValue
为空时,才会调用函数
OptionalLong::empty


但我不确定我是否会将
可选的
转换为
可选的
,除非我真的不得不这样做。正如前面的回答所说,在这种情况下,使用三元运算符可能是一种更好的方法。

请记住,如果您以任何方式涉及到
可选的
,您将在这种情况下受到性能的影响。摘自Joshua Bloch的《有效Java》,第3版:

“与返回基本类型相比,返回包含装箱基本类型的可选类型的成本过高,因为该可选类型具有两个装箱级别而不是零。[…]因此您不应返回装箱基本类型的可选类型,但“次要基本类型,
布尔值
字节
字符
,和
浮点值

没有理由在此处涉及
可选
。最好的解决方案是自己进行空检查,然后返回
可选长
,例如

OptionalLong millis(Date date) {
    return date == null ? OptionalLong.empty() : OptionalLong.of(date.getTime());
}

免责声明:可选在代码片段中用作参数仅用于演示目的。说“没有理由”是非常主观的。一个简单的原因可能是可读性。对于java,我们并不总是追求最有效的解决方案,只要两者都具有相同的O运行时(如本例中的
O(1)
)。此外,OP提供的代码可能只是一个示例。如果您已经有了一个
可选的
,我们可能希望使用“nicer”“解决方案OK,可读性可能是一个合理的理由。我的主要反对意见是,你最终得到的代码看起来非常漂亮,但幕后不必要地从
long
long
Optional
long
long
OptionalLong toLong(Optional<Long> o) {
    return  StreamEx.of(o).mapToLong(Long::longValue).findAny();
}
OptionalLong toLong(final Optional<Date> o) {
    return StreamEx.of(o).mapToLong(Date::getTime).findAny();
}
OptionalLong toOptionalLong(Optional<Long> optionalValue) {
    return optionalValue.map(OptionalLong::of).orElseGet(OptionalLong::empty);
}
OptionalLong millis(Date date) {
    return date == null ? OptionalLong.empty() : OptionalLong.of(date.getTime());
}