0

I was playing with Java's Optional and thought that it works like an if else block. But in the following code even if the name variable is not null the content of the orElse block get's executed. Any explanation?

import java.util.Optional;

class Scratch {
  public static void main(String[] args) {
    String name = "some text";
    System.out.println(
    Optional.ofNullable(name)
        .map(n -> mapped())
        .orElse(getOrElse()));

  }
  static String mapped(){
    System.out.println("mapped -- block executed");
    return "mapped";
  }
  static String getOrElse(){
    System.out.println("orElse -- block executed");
    return "orElse";
  }
}

Output:

mapped -- block executed
orElse -- block executed
mapped
Mureinik
  • 297,002
  • 52
  • 306
  • 350
forhadmethun
  • 535
  • 5
  • 16

2 Answers2

6

Have a closer look at Optional.orElse(T). It takes a value which needs to be provided to that call but that value will only be returned in the else case. So getOrElse() will be executed to get that value in any case.

Optional.orElse(T) is normally used with already existing values, e.g. like this: map(e -> mapped()).orElse("not found")

If you want to use a function that will only be called in the else case you need to use Optional.orElseGet(Supplier<? extends T>) like this: map(e -> mapped).orElseGet(Scratch::getOrElse) (or orElseGet(() -> getOrElse())).

Thomas
  • 87,414
  • 12
  • 119
  • 157
4

the orElse part is not being executed. Your getOrElse method is being executed in order to pass a value into orElse, but when the Optional is evaluated the orElse branch isn't retruned.

If you want to lazily evaluate it, you could use orElseGet and pass a method reference to it:

Optional.ofNullable(name)
    .map(n -> mapped())
    .orElseGet(Scratch::getOrElse));
Mureinik
  • 297,002
  • 52
  • 306
  • 350