I am trying to learn Java 8 feature Optional. I am confused about how Optional.orElse is working. Here is what i have tried:
public class OptionalsExample {
public static void main(String[] args) {
Name userName = new Name();
userName.setName("John Doe");
Optional<Name> optionalName = Optional.ofNullable(userName);
optionalName.ifPresent(
(Name value) -> {
Optional<String> optionalNameString = Optional.ofNullable(value.getName());
optionalNameString.ifPresent(name -> System.err.println("Name is: " + optionalNameString.get()));
}
);
}
private static void printError() {
System.err.println("No Name present");
}
}
My Concern is that if name is set everything works fine but when no name is set i want to execute orElse. I want to do something when i comment
userName.setName("John Doe");
like printing No Name Found
How can i do that?
TIA
Your usage of nested ifPresent
calls is very similar to the (nested) forEach
calls on streams, seen in a lot of other questions.
They are a clear sign that you should try better on functional thinking.
What you want to do is
System.out.println(
Optional.ofNullable(userName) // will be an empty optional if userName is null
.map(Name::getName) // will turn to empty optional if getName returns null
.map("Name is: "::concat) // prepend "Name is: " (only when we have a name)
.orElse("No Name Found") // get the result string or the alternative
);
The important point to understand, is, that the map
ping steps applied to an empty Optional
don’t do anything but return an empty Optional
again. Since you want to print in either case, the print statement is not passed as consumer, but written as stand-alone statement, printing the value returned by the orElse
invocation, which will be either, the non-null
result of the processing steps or the alternative String
.