2

I am using Java-8 's flatMap operation to make a part of my code smaller.

I know that if my code is as follows:

if (giftOptional.isPresent()) {
    Gift gift = giftOptional.get();
    Optional<Boolean> giftIsWrapped = gift.isWrapped();
    return giftIsWrapped.isPresent() && giftIsWrapped.get();
}
return false;

then it can be changed to:

return giftOptional.flatMap(Gift::isWrapped)
                   .orElse(Boolean.FALSE);

but what if the isWrapped method does not return an Optional? That is, if the code is like this:

if (giftOptional.isPresent()) {
    Gift gift = giftOptional.get();
    boolean giftIsWrapped = gift.isWrapped();
    return giftIsWrapped;
}
return false;

then can the same code apply? That is:

return giftOptional.flatMap(Gift::isWrapped)
                   .orElse(Boolean.FALSE);

Also, what if I need to add some argument to the function? For example, the code is:

if (giftOptional.isPresent()) {
    String gift = giftOptional.get();
    boolean giftIsWrapped = gift.equals("some string");
    return giftIsWrapped;
}
return false;

what should be the corresponding code using flatMap in that case?

2 Answers 2

3

You needed to use flatMap to unwrap or "flatten" the nested Optional. If isWrapped returns a boolean, simply use map instead of flatMap:

giftOptional.map(Gift::isWrapped).orElse(false);

You can always use a lambda expression inside map to express the mapping logic. In your case, you can use .map(gift -> gift.equals("some string")). That happens to be the same as "some string"::equals, but you cannot always reduce a lambda into a method reference.

The code above will work with any return type. However, since in your case you are dealing with a boolean, you can use filter instead of map:

giftOptional.filter(Gift::isWrapped).isPresent();
Sign up to request clarification or add additional context in comments.

1 Comment

Ah, got it, thanks. Can you please also tell me what do I do when I need to add an argument to the function? You can check the last part of my question if you want to look at an example code for reference.
2

You want filter():

return giftOptional.filter(Gift::isWrapped).orElse(Boolean.FALSE);

filter() takes a Predicate, which can be a method reference, and works as you would expect and as you want in your case.


You can still use filter() with a method reference for comparison with a String:

return giftOptional.filter("some string"::equals).orElse(Boolean.FALSE);

7 Comments

Got it, thanks. Would you also happen to know what should be the code if the function required an argument to be passed to it, as mentioned in the final part of my question?
@SanjibanBairagya see edited answer for alternate code
I'm afraid the solutions mentioned here are not compiling. I'm getting the following errors respectively: error: incompatible types: Boolean cannot be converted to Gift, and, error: incompatible types: Boolean cannot be converted to String
@SanjibanBairagya what code exactly is giving the error(s)?
@SanjibanBairagya because Predicate<T> is a Function<T, Boolean>, in this case map() and filter() are effectively the same thing. You should use whatever makes the code clearer,
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.