Jak przekonwertować możliwą wartość null na wartość domyślną za pomocą Guava?

Czy Guava dostarcza metodę, aby uzyskać wartość domyślną, jeśli przekazanym odniesieniem do obiektu jest null? Szukam czegoś w rodzaju <T> T nullToDefault(T obj, T default), były default jest zwracane, jeśli obj is null.

Tutaj na stackoverflow nic o tym nie znalazłem. Szukam tylko czystego rozwiązania Guava(jeśli istnieje)!

Nie znalazłem nic w API Gauva 10, tylko com.google.common.base.Objects wygląda obiecująco, ale brakuje czegoś podobnego.

 51
Author: Chriss, 2011-11-07

9 answers

W dodatku do Objects.firstNonNull, Guava 10.0 dodała klasę opcjonalny jako bardziej ogólne rozwiązanie tego typu problemu.

An Optional jest czymś, co może lub nie musi zawierać wartość. Istnieją różne sposoby tworzenia instancji Optional, ale w Twoim przypadku odpowiednia jest metoda fabryczna Optional.fromNullable(T).

Gdy masz Optional, możesz użyć jednej z metod or, aby uzyskać wartość Optional zawiera (jeśli zawiera wartość) lub inną wartość (jeśli ma nie).

Składając wszystko razem, twój prosty przykład wyglądałby następująco:

T value = Optional.fromNullable(obj).or(defaultValue);

Dodatkowa elastyczność Optional pojawia się, jeśli chcesz użyć Supplier jako wartości domyślnej (więc nie wykonujesz obliczeń, aby ją uzyskać, chyba że jest to konieczne) lub jeśli chcesz połączyć wiele opcjonalnych wartości razem, aby uzyskać pierwszą wartość, która jest obecna, na przykład:

T value = someOptional.or(someOtherOptional).or(someDefault);
 67
Author: ColinD,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-11-07 17:36:47

A może

MoreObjects.firstNonNull(obj, default)

Zobacz JavaDoc .

(Uwaga historyczna: klasa MoreObjects nazywała się Objects, ale została zmieniona, aby uniknąć pomyłki z java.util.Objects Klasa wprowadzona w Javie 7. Klasa Guava Objects jest obecnie skutecznie przestarzała.)

 55
Author: Simon Nickerson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-02-09 12:17:30

Jak wspomniano wcześniej, roztwór guawy jest poprawny.

Istnieje jednak czyste rozwiązanie JDK z Java 8 :

Optional.ofNullable( var ).orElse( defaultValue );

Zobacz dokumentację java.util.Optional

 32
Author: Nicolas Nobelis,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-09-07 11:37:30

To powinno załatwić sprawę: Objects.firstNonNull(o, default)
Zobacz guava API doc

 9
Author: Jens Hoffmann,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-11-07 16:39:19

Jeśli twój obiekt nie jest już opcjonalny, to opcjonalne / firstNotNull sugestie komplikują prostą funkcję Javy, operator ternary:

T myVal = (val != null) ? val : defaultVal;

Włączenie zależności i wywołania wielu metod wprowadza tyle samo złożoności odczytu, co operator trójkowy. Chciałbym nawet argumentować, że używanie Optional w przeciwieństwie do semantyki "moja metoda może, ale nie musi zwracać obiektu" jest czerwoną flagą, że robisz coś złego (tak jak w innych przypadkach, gdy ktoś nadużywa coś sprzecznego z tym znaczeniem semantycznym).

Zobacz http://alvinalexander.com/java/edu/pj/pj010018 więcej dyskusji na temat operatora trójdzielnego.

 7
Author: MonkeyWithDarts,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-08-24 18:28:45

Jeśli mówisz tylko o łańcuchach, istnieją również metody Apache Commons defaultString i defaultIfEmpty

DefaultString da Ci tylko wartość domyślną dla true null, podczas gdy defaultIfEmpty da ci wartość domyślną dla null lub pustego ciągu znaków.

Istnieje również defaultIfBlank, który da ci wartość domyślną nawet na pustym łańcuchu.

Np.

String description = "";
description = StringUtils.defaultIfBlank(description, "Theodore"); 

Opis będzie teraz równy "Theodore"

Edytuj: Apache Commons posiada również klasę ObjectUtils to nie ma domyślnych wartości null dla w pełni upieczonych obiektów...

 5
Author: Daniel Schmidt,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-06-15 18:20:04

Java.util.Objects and Guava ' s optional do provide nice way for getting overriding null to default values... używam ich dużo

Ale tu jest coś bardziej imperatywnego:

public static <T> T firstNotNuLL(T...args){
    for (T arg : args)
        if ( arg != null) return arg;
    throw new NullPointerException();  
}
 3
Author: kunwar.sangram,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-07-02 12:24:19

Dla twojej wiadomości, Java 9 ma dwie metody, które robią dokładnie to, co chcesz:

public static <T> T requireNonNullElse(T obj, T defaultObj);

I wersja leniwa:

public static <T> T requireNonNullElseGet(T obj, Supplier<? extends T> supplier)
 3
Author: ZhekaKozlov,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-10-11 03:52:16

Rozważ użycie Optional wbudowanego w Guava 10. Możesz połączyć wiele opcji, takich jak Optional.fromNullable(var).orNull() lub Optional.fromNullable(var).or(Optional.of(var2)).orNull()

 1
Author: Ray,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-11-07 17:38:08