Ich habe den folgenden Code, der für mehrere Nullprüfungen etwas hässlich ist.
String s = null;
if (str1 != null) {
s = str1;
} else if (str2 != null) {
s = str2;
} else if (str3 != null) {
s = str3;
} else {
s = str4;
}
Also habe ich versucht, Optional.ofNullable
wie unten zu verwenden, aber es ist immer noch schwer zu verstehen, wenn jemand meinen Code liest. Was ist der beste Ansatz, um dies in Java 8 zu tun?
String s = Optional.ofNullable(str1)
.orElse(Optional.ofNullable(str2)
.orElse(Optional.ofNullable(str3)
.orElse(str4)));
In Java 9 können wir Optional.ofNullable
mit verwenden OR
, aber in Java8 gibt es einen anderen Ansatz?
or
SyntaxString s = Optional.ofNullable(str1) .or(() -> Optional.ofNullable(str2)) .or(() -> Optional.ofNullable(str3)) .orElse(str4);
sieht nicht so gut aus wie die, dieStream.of
ich sya würde.StringUtils.firstNonBlank()
Antworten:
Sie können es so machen:
quelle
{str1, str2, str3}
) sehen viel langsamer aus als ein lokalesif
oder?:
, das die Java-Laufzeit optimieren kann. Gibt es eine Stream-spezifische Optimierung injavac
und die Java-Laufzeit, die es so schnell macht wie?:
? Wenn nicht, empfehle ich diese Lösung nicht für leistungskritischen Code.?:
Code und ich bin sicher, dass Sie es in leistungskritischem Code vermeiden sollten. Es ist jedoch viel besser lesbar und Sie sollten es in nicht leistungskritischem Code IMO empfehlen, der sicher mehr als 99% des Codes ausmacht.javac
noch zur Laufzeit. Dies schließt die allgemeinen Optimierungen wie das Inlinen des gesamten Codes und das anschließende Eliminieren redundanter Operationen nicht aus. Im Prinzip könnte das Endergebnis so effizient sein wie die einfachen bedingten Ausdrücke. Es ist jedoch eher unwahrscheinlich, dass es jemals dort ankommt, da die Laufzeit den erforderlichen Aufwand nur für die heißesten Codepfade aufwenden würde.str4
, die Parameter vonStream.of(...)
undorElse(null)
am Ende zu verwenden.Wie wäre es mit einem ternären bedingten Operator?
quelle
// take first non-null of str1..3
. Sobald Sie wissen, was es tut, wird es leicht zu sehen, wie.?:
Leiter sehen, wissen Sie, was sie tut. (Übrigens wissen funktionale Programmierer dies als(cond ...)
Klauseln: Es ist immer eine Wache, gefolgt von dem entsprechenden Wert, der verwendet werden soll, wenn die Wache wahr ist.)Sie können auch eine Schleife verwenden:
quelle
Aktuelle Antworten sind nett, aber Sie sollten das wirklich in eine Utility-Methode einfügen:
Diese Methode ist seit Jahren in meiner
Util
Klasse und macht Code viel sauberer:Sie können es sogar generisch machen:
quelle
Arrays.stream()
wenn ich dasselbe mit afor
und a tun kann!= null
, was effizienter ist. Und Todd hätte recht. Als ich diese Methode codierte, suchte ich jedoch nach einer Möglichkeit, dies mithilfe von Java 8-Funktionen wie OP zu tun.Ich benutze eine Hilfsfunktion, so etwas wie
Dann kann diese Art von Code geschrieben werden als
quelle
v0
Parameter?min
als Beispiel dient.) Ich bin weniger davon überzeugt, dass dies hier angemessen ist.firstNonNull(arr)
arr zurückgeben, wenn es nicht null ist. Wenn dies derfirstNonNull(T... vs)
Fall wäre, würde stattdessen der erste Nicht-Null-Eintrag in arr zurückgegeben.Eine Lösung, die auf so viele Elemente angewendet werden kann, wie Sie möchten, kann sein:
Sie können sich eine Lösung wie die folgende vorstellen, aber die erste sorgt
non nullity
für alle Elementequelle
str4
obwohl es tatsächlich eine Null istorElseNull
, was gleich ist, wennstr4
null ist.Sie können auch alle Strings in einem Array von Strings zusammenfassen und dann eine for-Schleife ausführen, um die Schleife zu überprüfen und zu verlassen, sobald sie zugewiesen ist. Angenommen, s1, s2, s3, s4 sind alle Strings.
Bearbeitet, um die Bedingung für die Standardeinstellung auf s4 zu setzen, wenn keine zugewiesen ist.
quelle
s4
(oderstr4
), dems
am Ende zugewiesen werden soll , auch wenn es null ist.Methodenbasiert und einfach.
Und benutze es als:
Es ist einfach mit Arrays zu tun und sieht hübsch aus.
quelle
Wenn Sie Apache Commons Lang 3 verwenden, kann es folgendermaßen geschrieben werden:
Die Nutzung
ObjectUtils.firstNonNull(T...)
wurde aus dieser entnommen Antwort . In verwandten Fragen wurden auch verschiedene Ansätze vorgestellt .quelle