Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I map an optional into a primitive optional?

I know I can map an Optional into an another wrapper type optional.

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

How can I map or flatMap into an OptionalLong?

OptionalLong millis(Date date) {
}

I tried but had no luck.

ofNullable(value).flatMap(v -> { // javac has never liked me
    return OptionalLong.of(v.getTime());
});
like image 269
Jin Kwon Avatar asked Dec 19 '22 07:12

Jin Kwon


2 Answers

You can use map to get an Optional<OptionalLong> then orElse to remove the outer Optional like this:

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>:

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();
}
like image 183
Alex - GlassEditor.com Avatar answered Dec 21 '22 21:12

Alex - GlassEditor.com


Keep in mind that you will take a performance hit in this scenario if you involve Optional<Long> in any way. From Joshua Bloch's Effective Java, 3rd Edition:

"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"

There is no reason to involve Optional here. The best solution is to do the null check yourself, and then return an OptionalLong, e.g.

OptionalLong millis(Date date) {
    return date == null ? OptionalLong.empty() : OptionalLong.of(date.getTime());
}
like image 41
Joshua Bone Avatar answered Dec 21 '22 20:12

Joshua Bone