Java 8 Optional instead of if

13,786

Solution 1

There is a very neat method for that, but present in jdk-9...

public void check(String name){
     Optional.ofNullable(name)
            .ifPresentOrElse(YourClass::doSomething, YourClass::doMore);
} 

assuming doSomething and doMore are static methods... If not an instance should be used, like this::doSomething or this::doMore

Solution 2

While there certainly is a way to create the same code using Optionals (e.g. see Eugene's answer) you should not use Optionals here (imho).

Either you would get the Optional passed into your method which creates a overhead for the caller and does not really make sense looking at why / for what use case Optional was introduced.
Or you would create the Optional yourself inside the method. That is more "okay" but very cumbersome, obscures what is actually happening and I would request it to be changed if I came across it during a code review. Just compare the snippet using an Optional and your current code - your code is probably shorter in terms of characters, it is obvious what is happening. The only upside of using Optionals here is that it seems to become a one-liner which is firstly nothing that is more important than readability and furthermore it is something you could achieve without it anyway if you would add some braces.


Bottom line: Your code is perfectly fine as it is.

Solution 3

You can avoid if statement by utilizing Java 8 Optional.map() and Optional.orElseGet() methods. Check following example:

import java.util.Optional;
import java.util.function.Consumer;

final class OptionalTestMain {

    public static void main(String[] args) {
        check("test", str -> {
            System.out.println("Yay, string is not null!");
            System.out.println("It's: " + str);
        }, () -> {
            System.out.println("Crap, string is a null...");
            System.out.println("There is nothing for me to do.");
        });

        check(null, str -> {
            System.out.println("Yay, string is not null!");
            System.out.println("It's: " + str);
        }, () -> {
            System.out.println("Crap, string is a null...");
            System.out.println("There is nothing for me to do.");
        });
    }

    static void check(String str, Consumer<String> ifPresent, Runnable ifNotPresent) {
        Optional.ofNullable(str)
                .map(s -> { ifPresent.accept(s); return s; })
                .orElseGet(() -> { ifNotPresent.run(); return null; });
    }
}

It will produce following output:

Yay, string is not null!
It's: test
Crap, string is a null...
There is nothing for me to do.

Method check expects 3 parameters:

  • a String (it may be null)
  • a Consumer lambda expression that does something with this value and does not mutate input value.
  • a Runnable lambda with no parameters to do something when input String is null.

Of course you could easily modify following method and then utilize the whole potential of Optional class, e.g.:

static String checkAndReturn(String str, Function<String, String> ifPresent, Supplier<String> ifNotPresent) {
    return Optional.ofNullable(str)
            .map(ifPresent)
            .orElseGet(ifNotPresent);
}

Then:

System.out.println(checkAndReturn("test", String::toUpperCase, () -> "no value"));
System.out.println(checkAndReturn(null, String::toUpperCase, () -> "no value"));

will produce following output:

TEST
no value

I hope it helps.

Solution 4

There is no reason to change your implementation. There is no way to do what you want in java 8 with an Optional without having an if, while respecting the idea of not using 'map' for side-effects.

I mean, you could have

public void check(String name) {
    Optional<String> nameOpt = Optional.ofNullable(name);
    nameOpt.ifPresent(n -> doSomething(n));
    if (!nameOpt.isPresent()) {
        doMore();
    }
}

but that has no sense. here you have a good article what Optional tries to resolve (and hence for what it's meant to be used): mainly for return types. Other stuff is just overusing it.

Share:
13,786
Mateusz Sobczak
Author by

Mateusz Sobczak

Updated on June 24, 2022

Comments

  • Mateusz Sobczak
    Mateusz Sobczak almost 2 years

    I have problem with Optional and I don't know how to handle it.

    public void check(String name) {
       if (name != null)
          doSomething(name);
       else 
          doMore();
    } 
    

    How to change this if into Optional?