Java 8 Optional instead of if
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 Optional
s (e.g. see Eugene's answer) you should not use Optional
s 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 inputString
isnull
.
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.
Mateusz Sobczak
Updated on June 24, 2022Comments
-
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?