简体   繁体   English

如何将可选项映射到原始可选项?

[英]How can I map an optional into a primitive optional?

I know I can map an Optional into an another wrapper type optional. 我知道我可以将Optional映射到另一个包装类型可选。

Optional<Long> millis(Date date) {
    return ofNullable(date).map(Date::getTime);
}

How can I map or flatMap into an OptionalLong ? 如何将mapflatMap mapOptionalLong

OptionalLong millis(Date date) {
}

I tried but had no luck. 我试过但没有运气。

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

You can use map to get an Optional<OptionalLong> then orElse to remove the outer Optional like this: 您可以使用map来获取Optional<OptionalLong>然后使用orElse删除外部Optional如下所示:

OptionalLong millis(Date date) {
    return Optional.ofNullable(date).map(Date::getTime)
            .map(OptionalLong::of).orElse(OptionalLong.empty());
}

Another (shorter in this case) way is to use the ternary operator instead: 另一种(在这种情况下更短)的方式是使用三元运算符:

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

Or if you already have the Optional<Long> : 或者,如果您已经拥有Optional<Long>

OptionalLong toOptionalLong(Optional<Long> o) {
    return o.map(OptionalLong::of).orElse(OptionalLong.empty());
}
OptionalLong toOptionalLong(Optional<Long> o) {
    return o.isPresent() ? OptionalLong.of(o.get()) : OptionalLong.empty();
}

Keep in mind that you will take a performance hit in this scenario if you involve Optional<Long> in any way. 请记住,如果您以任何方式涉及Optional<Long> ,您在此方案中获得性能提升。 From Joshua Bloch's Effective Java, 3rd Edition : 来自Joshua Bloch的Effective Java,第3版

"Returning an optional that contains a boxed primitive type is prohibitively expensive compared to returning the primitive type because the optional has two levels of boxing instead of zero. [...] Therefore you should never return an optional of a boxed primitive type , with the possible exception of the "minor primitive types," Boolean , Byte , Character , Short , and Float " “返回包含盒装基元类型的可选项与返回基元类型相比非常昂贵,因为可选项具有两个级别的装箱而不是零。[...]因此, 您永远不应返回可选的盒装基元类型 , “次要基本类型”, BooleanByteCharacterShortFloat的可能例外“

There is no reason to involve Optional here. 没有理由在这里涉及Optional The best solution is to do the null check yourself, and then return an OptionalLong , eg 最好的解决方案是自己进行空检查,然后返回一个OptionalLong ,例如

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

Using the StreamEx library 使用StreamEx库

OptionalLong millis(final Date date) {  
   return StreamEx.ofNullable(date).mapToLong(Date::getTime).findAny();
}

or 要么

OptionalLong toLong(Optional<Long> o) {
    return  StreamEx.of(o).mapToLong(Long::longValue).findAny();
}

or 要么

OptionalLong toLong(final Optional<Date> o) {
    return StreamEx.of(o).mapToLong(Date::getTime).findAny();
}

I would implement it as follows: 我会按如下方式实现它:

OptionalLong toOptionalLong(Optional<Long> optionalValue) {
    return optionalValue.map(OptionalLong::of).orElseGet(OptionalLong::empty);
}

The function OptionalLong::empty is called if and only if the optionalValue is empty. 当且仅当optionalValue为空时,才调用OptionalLong::empty函数。

But I'm not sure I would cast an Optional<Long> into an OptionalLong unless I'm really obliged to. 但我不确定我是否会将Optional<Long>强制转换为OptionalLong除非我真的有义务。 As said in former answers, using a ternary operator is probably a better approach in this case. 如前面的答案所述,在这种情况下,使用三元运算符可能是更好的方法。

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

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