Mam poniższy kod, który jest trochę brzydki dla wielu sprawdzeń zerowych.
String s = null;
if (str1 != null) {
s = str1;
} else if (str2 != null) {
s = str2;
} else if (str3 != null) {
s = str3;
} else {
s = str4;
}
Spróbowałem więc użyć Optional.ofNullable
poniższego, ale nadal trudno jest zrozumieć, czy ktoś czyta mój kod. jakie jest najlepsze podejście do tego w Javie 8.
String s = Optional.ofNullable(str1)
.orElse(Optional.ofNullable(str2)
.orElse(Optional.ofNullable(str3)
.orElse(str4)));
W Javie 9 możemy używać Optional.ofNullable
z OR
, Ale czy w Javie8 jest jakieś inne podejście?
or
Składnia Java9String s = Optional.ofNullable(str1) .or(() -> Optional.ofNullable(str2)) .or(() -> Optional.ofNullable(str3)) .orElse(str4);
nie wygląda tak dobrze, jakStream.of
ja bym sya.StringUtils.firstNonBlank()
Odpowiedzi:
Możesz to zrobić tak:
źródło
{str1, str2, str3}
) wygląda na znacznie wolniejsze niż lokalneif
lub?:
, które środowisko wykonawcze Java może zoptymalizować. Czy jest jakaś optymalizacja specyficzna dla Streamjavac
i środowisko wykonawcze Java, które sprawia, że jest tak szybki?:
? Jeśli nie, nie polecę tego rozwiązania w kodzie krytycznym dla wydajności.?:
kod i jestem pewien, że należy tego unikać w kodzie krytycznym dla wydajności. Jest jednak znacznie bardziej czytelny i powinieneś go polecać w IMO z kodem niekrytycznym dla wydajności, który z pewnością stanowi ponad 99% kodu.javac
ani w środowisku wykonawczym. Nie wyklucza to ogólnych optymalizacji, takich jak wstawianie całego kodu, a następnie eliminowanie zbędnych operacji. Zasadniczo wynik końcowy może być tak samo wydajny, jak zwykłe wyrażenia warunkowe, jednak jest raczej mało prawdopodobne, aby kiedykolwiek się tam znalazł, ponieważ środowisko wykonawcze poświęciłoby niezbędny wysiłek tylko na najgorętsze ścieżki kodu.str4
do parametrówStream.of(...)
i wykorzystanieorElse(null)
na końcu.A co z potrójnym operatorem warunkowym?
źródło
// take first non-null of str1..3
. Kiedy już wiesz, co robi, łatwo jest zobaczyć, jak to zrobić.?:
drabinę, będziesz wiedział, co robi. (Btw, programiści funkcjonalne wiedzą o tym jak(cond ...)
klauzul. To zawsze straż szła przez odpowiednią wartość do użycia, gdy osłona jest prawdą)Możesz także użyć pętli:
źródło
Aktualne odpowiedzi są fajne, ale naprawdę powinieneś to umieścić w metodzie narzędziowej:
Ta metoda jest w mojej
Util
klasie od lat, dzięki czemu kod jest znacznie czystszy:Możesz nawet uczynić go ogólnym:
źródło
Arrays.stream()
kiedy mogę zrobić to samo z afor
i a!= null
, co jest bardziej wydajne. I Todd miałby rację. Jednak kiedy kodowałem tę metodę, szukałem sposobu na zrobienie tego za pomocą funkcji Java 8, tak jak OP, więc jest to.Używam funkcji pomocniczej, coś w stylu
Następnie ten rodzaj kodu można zapisać jako
źródło
v0
parametr?min
jako przykładu). Jestem mniej przekonany, że jest to właściwe w tym miejscu.firstNonNull(arr)
zwrócić arr, jeśli nie jest zerowy. Gdyby tak byłofirstNonNull(T... vs)
, zamiast tego zwróciłoby pierwszy niezerowy wpis w arr.Rozwiązaniem, które można zastosować do dowolnej liczby elementów, może być:
Można sobie wyobrazić rozwiązanie jak poniżej, ale to pierwsze zapewnia
non nullity
wszystkie elementyźródło
str4
mimo że jest to właściwie zeroorElseNull
, co oznacza to samo, jeślistr4
jest null.Możesz również wrzucić wszystkie Strings do tablicy String, a następnie wykonać pętlę for, aby sprawdzić i przerwać pętlę po jej przypisaniu. Zakładając, że wszystkie s1, s2, s3, s4 są ciągami.
Edytowane w celu wprowadzenia warunku domyślnego na s4, jeśli żaden nie jest przypisany.
źródło
s4
(lubstr4
), do którego ma zostaćs
ostatecznie przypisany , nawet jeśli jest pusty.Oparta na metodzie i prosta.
I użyj go jako:
Jest to proste w przypadku tablic i wygląda ładnie.
źródło
Jeśli korzystasz z Apache Commons Lang 3, możesz to zapisać w ten sposób:
Wykorzystanie
ObjectUtils.firstNonNull(T...)
zostało zaczerpnięte z tej odpowiedzi . W pokrewnym pytaniu przedstawiono również różne podejścia .źródło