Was ist der eleganteste Weg, um Optionen kombinieren?
Hier ist, was ich habe, so weit:
Optional<Foo> firstChoice = firstChoice();
Optional<Foo> secondChoice = secondChoice();
return Optional.ofNullable(firstChoice.orElse(secondChoice.orElse(null)));
Diese Streiks mich als abscheulichen und verschwenderischen. Wenn firstChoice ist vorhanden, ich bin unnötig computing secondChoice.
Es gibt auch eine effizientere version:
Optional<Foo> firstChoice = firstChoice();
if(firstChoice.isPresent()) {
return firstChoice;
} else {
return secondChoice();
}
Hier kann ich nicht Kette einige mapping-Funktion, um das Ende, ohne duplizieren der mapper oder deklarieren eine lokale variable. All dies macht den code komplizierter als das eigentliche problem gelöst wird.
Ich würde viel lieber schreiben diese:
return firstChoice().alternatively(secondChoice());
Jedoch Optional::alternativ natürlich nicht vorhanden. Was nun?
- mögliche Duplikate von Get Wert aus einem Optionalen oder anderen
- ... wenn konfrontiert mit dem problem der null ... jetzt haben wir zwei Probleme.
- Btw, Paul Sandoz nur veröffentlicht, changeset für das review, das stellt
Optional.or()
Methode, die genau das tut, was Sie wollen:firstChoice().or(this::secondChoice)
. Mehr Infos unter JDK-8080418. In Java-9-mal werden wir glücklich sein!
Du musst angemeldet sein, um einen Kommentar abzugeben.
Versuchen Sie dies:
Die map-Methode gibt Ihnen einen
Optional<Optional<Foo>>
. Dann, dieorElseGet
Methode flacht diese wieder zu einemOptional<Foo>
. DiesecondChoice
Methode wird nur ausgewertet werden, wennfirstChoice()
gibt die leeren optional.Optional::or
Methode. Dies könnte also geschrieben werdenfirstChoice().or(this::secondChoice)
in Java 9.this::secondChoice
gibt eineSupplier
eher alsOptional
- das Beispiel aus dem OP nicht.Supplier
. Es ist eine Methode verweisen.Optional
.this::secondChoice
ist eine Methode, Referenz vom TypSupplier<Optional<Foo>>
. Wenn Sie die Methode aufrufen, Verweis erhalten Sie dieOptional
. Das Beispiel in der Antwort funktioniert für Java 8 und höher.Können Sie einfach ersetzen,
Den oben genannten code nicht nennen, es sei denn firstChoice.isPresent() ist falsch.
Aber Sie müssen darauf vorbereitet sein zu nennen, die beide Funktionen, um die gewünschte Ausgabe erhalten. Es gibt keinen anderen Weg, um zu entkommen die Prüfung.
Aufruf zur zweiten Wahl.
Vielleicht so etwas wie dieses :
Aus : Verkettung Optionen in Java 8
Hier ist die Verallgemeinerung von @marstran Lösung für eine beliebige Anzahl von Optionen:
Test:
Ausgabe:
Ich war frustriert genug, durch die Tatsache, dass diese nicht unterstützt in java 8, die ich wieder eingeschaltet, um Guave ist Optionen die
oder
:Faul Berechnungen und beliebige Anzahl von
Optional
ElementeHier ist ein Weg, der funktioniert für eine beliebige Anzahl von
Optional
's in einem stream API:Es ist nicht der kürzeste. Aber mehr schlicht und verständlich.
Andere Möglichkeit ist die Verwendung
firstNonNull()
aus Guave von commons-lang, wenn Sie bereits mit einer dieser Bibliotheken:if
Lösung in der Frage, btw.Optional
s. Dies ist der Grund, warum ich sagte, dass dieser Weg funktioniert für beliebig vieleOptional
s.firstChoice()
undsecondChoice()
sind eigentlich Methoden, und man kann nicht einfach ändern Sie Ihre Lösung weglassen beim Aufruf der zweiten, wenn die erste, die nicht leer sind optional.findFirst()
definiert als kurz-circuting Betrieb in der Dokumentation. Sie können leicht überprüfen, dassOptional.get()
undOptional.isPresent()
Methoden nur einmal aufgerufen werden, mit debugger.