Quelle est la façon la plus élégante de combiner les options?
Voici ce que j'ai obtenu jusqu'à présent:
Optional<Foo> firstChoice = firstChoice();
Optional<Foo> secondChoice = secondChoice();
return Optional.ofNullable(firstChoice.orElse(secondChoice.orElse(null)));
Cela me semble à la fois hideux et de gaspillage. Si firstChoice est présent, je suis inutilement de l'informatique secondChoice.
Il y a également une plus efficace version:
Optional<Foo> firstChoice = firstChoice();
if(firstChoice.isPresent()) {
return firstChoice;
} else {
return secondChoice();
}
Ici je ne peux pas la chaîne certaine fonction de mappage à la fin, sans dupliquer le mappeur ou la déclaration d'une autre variable locale. Tout cela rend le code plus compliqué que le réel problème étant résolu.
Je préfère être écrit ceci:
return firstChoice().alternatively(secondChoice());
Cependant Facultatif::sinon, évidemment, n'existe pas. Maintenant ce qui?
- double possible de Obtenir la valeur d'une Option ou d'une autre
- ... lorsque l'on est confronté avec le problème de la valeur null, " maintenant, nous avons deux problèmes.
- Btw, Paul Sandoz vient de publier un changeset pour l'examen qui introduit
Optional.or()
méthode, qui fait exactement ce que vous voulez:firstChoice().or(this::secondChoice)
. Plus d'infos sur JDK-8080418. En Java-9 fois nous allons être heureux!
Vous devez vous connecter pour publier un commentaire.
Essayez ceci:
La méthode map vous donne un
Optional<Optional<Foo>>
. Ensuite, leorElseGet
méthode aplatit ce retour à uneOptional<Foo>
. LesecondChoice
méthode sera évaluée uniquement sifirstChoice()
retourne le vide en option.Optional::or
méthode. Cela pourrait donc être écritefirstChoice().or(this::secondChoice)
en Java 9.this::secondChoice
renvoie uneSupplier
plutôt queOptional
- l'exemple de l'OP n'a pas.Supplier
. C'est une méthode de référence.Optional
.this::secondChoice
est une référence à une méthode de typeSupplier<Optional<Foo>>
. Si vous appelez la méthode de référence, vous obtenez leOptional
. L'exemple de la réponse qui fonctionne pour Java 8 et ainsi de suite.Vous pouvez simplement remplacer qu'avec,
Le code ci-dessus ne seront pas appel, à moins que firstChoice.isPresent() est faux.
Mais vous avez à préparer pour appeler à la fois des fonctions pour obtenir le résultat souhaité. Il n'y a pas d'autre moyen d'échapper à la vérification.
appel pour le deuxième choix.
Peut-être quelque chose comme ceci :
À partir de : Le chaînage d'Options en Java 8
Voici la généralisation de @marstran solution pour un certain nombre d'options:
Test:
De sortie:
J'ai été assez frustré par le fait que ce n'était pas prise en charge par java 8, que je suis passé de retour à la goyave est options qui ont
ou
:Paresseux calculs et nombre arbitraire de
Optional
élémentsIci est un moyen qui fonctionne pour un nombre arbitraire de
Optional
's dans un flux de données de l'API:Ce n'est pas le plus court. Mais plus clair et compréhensible.
Une autre façon est d'utiliser des
firstNonNull()
de Goyave de commons-lang si vous utilisez déjà l'un de ces bibliothèques:if
solution à la question, d'ailleurs.Optional
s. C'est pourquoi j'ai dit que cette méthode fonctionne pour nombre arbitraire deOptional
s.firstChoice()
etsecondChoice()
sont en fait des méthodes, et vous ne peut pas simplement modifier votre solution d'omettre de l'appel de la deuxième si le premier produit non-vide en option.findFirst()
défini comme un court-circuting opération dans la documentation. Vous pouvez facilement vérifier queOptional.get()
etOptional.isPresent()
méthodes appelé qu'une seule fois à l'aide du débogueur.