5

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

silentsudo
  • 6,730
  • 6
  • 39
  • 81
  • 2
    When you write `optionalNameString.ifPresent(name -> …)`, the actual `String` is already provided in the `name` parameter, so it makes no sense to invoke `get()` on the `optionalNameString` within the lambda expression. Similarly, it wouldn’t make any sense to invoke `orElse` at this place as the lambda expression won’t get executed when the `Optional` is empty. – Holger May 27 '16 at 14:53

2 Answers2

12

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 mapping 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.

Holger
  • 285,553
  • 42
  • 434
  • 765
-1

The orElse method allows you to return an alternative value when there isn't one in the Optional.

If you just want to print out an alternative String you can use the orElse method to return an alternative String:

Optional<String> optionalNameString = Optional.ofNullable(value.getName());
System.out.println(optionalNameString.orElse("Name is not present"));

Otherwise you can just check if the value is present using isPresent()

Optional<String> optionalNameString = Optional.ofNullable(value.getName());
if(optionalNameString.isPresent()) {
    // do something
} else {
    //do something else
}
explv
  • 2,709
  • 10
  • 17