web-dev-qa-db-fra.com

Évitez NoSuchElementException avec Stream

J'ai le suivant Stream:

Stream<T> stream = stream();

T result = stream.filter(t -> {
    double x = getX(t);
    double y = getY(t);
    return (x == tx && y == ty);
}).findFirst().get();

return result;

Cependant, il n'y a pas toujours un résultat qui me donne l'erreur suivante:

NoSuchElementException: Aucune valeur présente

Alors, comment puis-je retourner un null s'il n'y a pas de valeur?

43
clankill3r

Vous pouvez utiliser Optional.orElse , c’est beaucoup plus simple que de vérifier isPresent:

T result = stream.filter(t -> {
    double x = getX(t);
    double y = getY(t);
    return (x == tx && y == ty);
}).findFirst().orElse(null);

return result;
79
Tagir Valeev

Stream#findFirst() renvoie un Optional qui existe spécifiquement pour que vous n'ayez pas à utiliser les valeurs null.

Un objet conteneur pouvant contenir ou non une valeur non nulle. Si une valeur est présente, isPresent() renverra true et get() renverra la valeur.

Sinon, Optional#get() lance un NoSuchElementException.

Si une valeur est présente dans ce Optional, la renvoie, sinon jette NoSuchElementException.

Un Optional n'exposera jamais sa valeur s'il s'agit de null.

Si vous devez vraiment , vérifiez simplement isPresent() et renvoyez vous-même null.

Stream<T> stream = stream();

Optional<T> result = stream.filter(t -> {
    double x = getX(t);
    double y = getY(t);
    return (x == tx && y == ty);
}).findFirst();

if (result.isPresent()) 
    return result.get();
return null;
23

Une autre méthode pour remplacer Optional.get (qui échoue probablement avec l'intention de l'utilisateur avec une exception NoSuchElementException) consiste à utiliser une API plus détaillée qui est introduite dans JDK10 et appelée Optional.orElseThrow() . Dans mots de l'auteur -

Optional.get() est une "nuisance attrayante" et est trop tentant pour les programmeurs, ce qui entraîne des erreurs fréquentes. Les gens ne s'attendent pas à ce qu'un getter lève une exception. Une API de remplacement pour Optional.get() avec une sémantique équivalente devrait être ajoutée.

Remarque: - L'implémentation sous-jacente de ces deux API est identique, mais cette dernière indique plus clairement qu'une exception NoSuchElementException serait renvoyé par défaut si la valeur absente correspond à l'implémentation existante de Optional.orElseThrow​(Supplier<? extends X> exceptionSupplier) utilisée par les consommateurs comme alternative explicite.

0
Naman