Utilisation correcte de L'option.ifPresent()
je suis en train d'essayer de comprendre l' ifPresent()
méthode de l' Optional
API en Java 8.
j'ai une simple logique:
Optional<User> user=...
user.ifPresent(doSomethingWithUser(user.get()));
Mais cela provoque une erreur de compilation:
ifPresent(java.util.functionError:(186, 74) java: 'void' type not allowed here)
bien sûr, je peux faire quelque chose comme ceci:
if(user.isPresent())
{
doSomethingWithUser(user.get());
}
Mais c'est exactement comme une encombré null
vérifier.
Si je change le code:
user.ifPresent(new Consumer<User>() {
@Override public void accept(User user) {
doSomethingWithUser(user.get());
}
});
Le code est de plus en plus sale, qui me fait penser à revenir à l'ancien null
vérifier.
des idées?
4 réponses
Optional<User>.ifPresent()
prend un Consumer<? super User>
comme argument. Vous lui donnez une expression dont le type est vide. Donc ça ne compile pas.
Un Consommateur est destiné à être mis en œuvre comme une expression lambda:
Optional<User> user = ...
user.ifPresent(theUser -> doSomethingWithUser(theUser));
ou encore plus simple, en utilisant une référence de méthode:
Optional<User> user = ...
user.ifPresent(this::doSomethingWithUser);
C'est essentiellement la même chose que
Optional<User> user = ...
user.ifPresent(new Consumer<User>() {
@Override
public void accept(User theUser) {
doSomethingWithUser(theUser);
}
});
l'idée est que Le doSomethingWithUser()
appel de la méthode ne sera exécutée que si l'utilisateur est présent. Votre code exécute l'appel de méthode directement, et tente de passer son voir résultat à ifPresent()
.
en plus de la réponse de @JBNizet, mon cas d'usage général pour ifPresent est de combiner .isPresent()
et .get()
:
à l'Ancienne:
Optional opt = getIntOptional();
if(opt.isPresent()) {
Integer value = opt.get();
// do something with value
}
Nouvelle façon:
Optional opt = getIntOptional();
opt.ifPresent(value -> {
// do something with value
})
ceci, pour moi, est plus intuitif.
utilisez flatMap. Si une valeur est présente, flatMap renvoie un flux séquentiel contenant seulement cette valeur, sinon renvoie un flux vide. Donc, il n'est pas nécessaire d'utiliser ifPresent()
. Exemple:
list.stream().map(data -> data.getSomeValue).map(this::getOptinalValue).flatMap(Optional::stream).collect(Collectors.toList());
Vous avez besoin de l'utiliser comme ceci:
user.ifPresent(ClassNameWhereMethodIs::doSomethingWithUser);
Méthode ifPresent()
get Consumer
objet comme un paremeter et (de JavaDoc): "si une valeur est présente, invoquez le consommateur spécifié avec la valeur."La valeur de la variable user
.