I am trying to understand the ifPresent()
method of the Optional
API in Java 8.
I have simple logic:
Optional<User> user=...
user.ifPresent(doSomethingWithUser(user.get()));
But this results in a compilation error:
ifPresent(java.util.functionError:(186, 74) java: 'void' type not allowed here)
Of course I can do something like this:
if(user.isPresent())
{
doSomethingWithUser(user.get());
}
But this is exactly like a cluttered null
check.
If I change the code into this:
user.ifPresent(new Consumer<User>() {
@Override public void accept(User user) {
doSomethingWithUser(user.get());
}
});
The code is getting dirtier, which makes me think of going back to the old null
check.
Any ideas?
Why making simple when you can write some complicated code !
Indeed, if you will absolutely use
Optional
class, the simple code is what you have already written ...This code has the advantages to be
It is not because Oracle has added
Optional
class in Java 8 that this class must me used in all situation.You need to use it like this:
Method
ifPresent()
getConsumer
object as a paremeter and (from JavaDoc): "If a value is present, invoke the specified consumer with the value." Value its your variableuser
.Optional<User>.ifPresent()
takes aConsumer<? super User>
as argument. You're passing it an expression whose type is void. So that doesn't compile.A Consumer is intended to be implemented as a lambda expression:
Or even simpler, using a method reference:
This is basically the same thing as
The idea is that the
doSomethingWithUser()
method call will only be executed if the user is present. Your code executes the method call directly, and tries to pass its voir result toifPresent()
.In addition to @JBNizet's answer, my general use case for ifPresent is to combine
.isPresent()
and.get()
:Old way:
New way:
This, to me, is more intuitive.
Use flatMap. If a value is present, flatMap returns a sequential Stream containing only that value, otherwise returns an empty Stream. So there is no need to use
ifPresent()
. Example: