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?

44
demandé sur Tagir Valeev 2014-06-15 13:33:29

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().

78
répondu JB Nizet 2014-06-15 09:41:56

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.

7
répondu cst1992 2017-04-26 07:34:40

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());
3
répondu Taras Melnyk 2018-03-20 15:39:26

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.

2
répondu Aleksandr Podkutin 2014-06-15 09:45:07