Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can Java Optional be used for flow control?

I couldn't find a way to do the following with Java's Optional:

if (SOME_OBJECT != null) {
  doSomething(SOME_OBJECT);
} else {
  doSomethingElse();
}

By using Optional, I don't mean mean replacing SOME_OBJECT == null with Optional.ofNullable(SOME_OBJECT).isPresent(), which a much longer syntax than simply checking if null.

What I would expect is something like:

Optional.ofNullable(SOME_OBJECT)
  .ifPresent(this::doSomething)
  .orElse(this::doSomethingElse);

I couldn't find an API like the one I just wrote. Does it exist? If so, what is it? If not, why not? :)

The second piece of code looks like an anti-pattern :( Why? Perhaps Java's architects prevented this syntax on purpose...

like image 274
AlikElzin-kilaka Avatar asked Apr 23 '17 15:04

AlikElzin-kilaka


3 Answers

As mentioned in this Blog Article, Optionals will get a new method in Java 9: void ifPresentOrElse(Consumer<? super T> action, Runnable emptyAction). So, with Java, 8 you don't have something like that at the moment.

like image 99
Skgland Avatar answered Oct 24 '22 07:10

Skgland


As BdoubleB97 (Bdubzz) stated, Java 9 will implement Optional#ifPresentOrElse which will take a Consumer<T> which will be applied if the Optional<T> is present, and a Runnable which will be executed if the Optional<T> is empty.

You can either update now to the Java 9 Early Access build, or you can build the method yourself with the following:

public <T> void ifPresentOrElse(Optional<T> optional, Consumer<? super T> action, Runnable emptyAction) {
    if (optional.isPresent()) {
        action.accept(optional.get());
    } else {
        emptyAction.run();
    }
}
like image 43
Jacob G. Avatar answered Oct 24 '22 09:10

Jacob G.


As said Java 8 does not have a construct to do exactly what you want.

I know, it's ugly, far less readable than a simple if/then/else but you can do this:

Optional.ofNullable(someObject)
        .map(obj -> {
            System.out.println("present");
            return obj;
          })
        .orElseGet(() -> {
            System.out.println("not present");
            return null;
          });

The only side effect is that you have always return something.
Or on the other hand you can handle cleanly the case isPresent().

Optional.ofNullable(someObject).ifPresent(obj -> {
  System.out.println("present");
});
like image 2
freedev Avatar answered Oct 24 '22 09:10

freedev