Guava if else

0

Czy poniższy kod można zamienić na jakiś ładny jednolinijkowiec z Guavy?

   private BigDecimal convertToBigDecimal(Double price){
      if(price != null){
        return BigDecimal.valueOf(price);
     }

     return null;
   }

Jest taka fajna metoda MoreObject.firstNonNull(arg0, arg1) ktora zwraca pierwszy argument lub drugi jesli pierwszy jest nullem.

A chcialbym cos w stylu fun(arg0, arg1, arg2), ktora dzialalaby jak if else, zwracam arg1 jesli arg0 != null lub arg2 jesli arg0 == null.

4

Moze po prostu operator "? : ".

return price != null ? BigDecimal.valueOf(price) : null 
0

Chwilowe zaćmienie... oczywiście, wystarczy, zawsze używam... Jakoś skupiłem się na Guavie i zapomniałem o całej reszcie :)

0

@niezdecydowany: dlaczego zwracanie nulla często uważane jest za złą praktykę?

Ogólnie zgadzam się, że warto unikać. Po to powstaly np. StringUtils albo CollectionUtils w Apache Commons. Dzięki temu są popularne metody, znacznie odporniejsze na awarie (NullPointerException) i wymagające napisania mniej kodu0niż te w bibliotece standardowej. I słusznie tam null to zło: można było go uniknąć i fajnie zostało to zrobione.

Co zrobić w przypadku, gdy chcę wskazać, że wartość nie istnieje? W końcu null do tego służy, pokazuje, że referencja nie jest nigdzie przypisana. Czasem po prostu wartość może nie istnieć (podobnie jak w bazach danych, gdzie nulli wygodnie jest unikać, jednak nie zawsze jest to możliwe). Nie zawsze możemy zwrócić sensowną domyślną wartość dla nieistniejącej wartości.

Czasem też kolekcje zwracają null i jest to zupełnie ok. Np. mapa, z której pobiera sie klucz, do którego nie ma żadnej wartości zwraca null. I znając API odpowiednio to obsługujemy. I nie ma żadnego problemu.

Dlaczego więc zawsze unikać null? Dlaczego optional jest lepsze? Programuje w JDK 1.7. Chyba ma sens wtedy, gdy mamy pomysł na domyślną wartość (co nie zawsze musi działać).

0
NiebieskiFlaming napisał(a):

@niezdecydowany: dlaczego zwracanie nulla często uważane jest za złą praktykę?

Ogólnie zgadzam się, że warto unikać. Po to powstaly np. StringUtils albo CollectionUtils w Apache Commons. Dzięki temu są popularne metody, znacznie odporniejsze na awarie (NullPointerException) i wymagające napisania mniej kodu0niż te w bibliotece standardowej. I słusznie tam null to zło: można było go uniknąć i fajnie zostało to zrobione.

Co zrobić w przypadku, gdy chcę wskazać, że wartość nie istnieje? W końcu null do tego służy, pokazuje, że referencja nie jest nigdzie przypisana. Czasem po prostu wartość może nie istnieć (podobnie jak w bazach danych, gdzie nulli wygodnie jest unikać, jednak nie zawsze jest to możliwe). Nie zawsze możemy zwrócić sensowną domyślną wartość dla nieistniejącej wartości.

Czasem też kolekcje zwracają null i jest to zupełnie ok. Np. mapa, z której pobiera sie klucz, do którego nie ma żadnej wartości zwraca null. I znając API odpowiednio to obsługujemy. I nie ma żadnego problemu.

Dlaczego więc zawsze unikać null? Dlaczego optional jest lepsze? Programuje w JDK 1.7. Chyba ma sens wtedy, gdy mamy pomysł na domyślną wartość (co nie zawsze musi działać).

To że w javie jest .wait i .notifaj nie znaczy że powinieneś tego używać, po to są wzorce żeby wymusić na "mniej przewidywalnych" programistach bezpieczeństwo - za dużo razy w mojej bardzo któtkiej karierze spotkałem się z idoitycznumi null pointerami dlatego że ktoś zwrócić nulla bo nie pomyślał.

Zresztą to nie ja piszę - polecam Clean Code Robert C.

P.S nie byłbym sobą gdybym tego nie napisał: nie interesuje mnie specjalnie Twoje zdanie.

P.S Optional może zawierać nulla.

1

@niezdecydowny: no tak, lepiej jak malpka bezmyslnie powtarzac to co pisza w ksiazkach (specjalnosc kinder developerow). Wzorce projektowe sa dobre w 95% przypadkow. Uzywanie na sile wzorca tam, gdzie nie pasuje to tez jest antypattern.

0
NiebieskiFlaming napisał(a):

@niezdecydowny: no tak, lepiej jak malpka bezmyslnie powtarzac to co pisza w ksiazkach (specjalnosc kinder developerow). Wzorce projektowe sa dobre w 95% przypadkow. Uzywanie na sile wzorca tam, gdzie nie pasuje to tez jest antypattern.

nie mamy za bardzo o czym gadać.

0

niezdecydowany, ogólnie to widzę, że masz problemy ze sobą. Czytając twoje komentarze można dojść do wniosku, że jesteś psychicznie niedorozwinięty. #anonim

1
Telefon Diabła napisał(a):

niezdecydowany, ogólnie to widzę, że masz problemy ze sobą. Czytając twoje komentarze można dojść do wniosku, że jesteś psychicznie niedorozwinięty. #anonim

Zresztą chłopcze,

Co zrobić w przypadku, gdy chcę wskazać, że wartość nie istnieje? W końcu null do tego służy

Po takim tekście mogę jedynie zapytać, czy książki z przyrody na poniedziałek spakowane ?

0

Jeżeli zdecydujemy się na powszechne używanie Optional zamiast nulla, to w czasie pisania kodu wiemy w którym miejscu możemy mieć wartość pustą, a w którym nie, dzięki statycznemu typowaniu. Jeżeli zdecydujemy się używać wartości null, to wtedy cały kod będzie usiany null-checkami, bo z kodu nie wywnioskuje się, gdzie się można nulla spodziewać.

Czasem też kolekcje zwracają null i jest to zupełnie ok. Np. mapa, z której pobiera sie klucz, do którego nie ma żadnej wartości zwraca null. I znając API odpowiednio to obsługujemy. I nie ma żadnego problemu.

Kolekcje powstały przed Optionalem, dlatego go nie używają.

null czasem jest upierdliwy. Przez to, że kolekcje nie zwracają Optionala nie można np zrobić:

return mapa.getOptional(key).map(processValue).orElse(defaultValue);

Za to trzeba robić:

T value = mapa.get(key);
return value == null ? defaultValue : processValue(value);

Tutaj zysk jest niewielki, ale co się stanie, gdy processValue też może zwrócić pustą wartość i mamy też funkcję processValue2 którą chcemy złożyć z pierwszą?
Kod konwencjonalny:

T value = mapa.get(key);
U value1 = value == null ? null : processValue(value);
V value2 = value1 == null ? null : processValue2(value1);
return value2 == null ? defaultValue : value2;

Kod z Optionalem:

return mapa.getOptional(key).flatMap(processValue).flatMap(processValue2).orElse(defaultValue);

Znacznie czytelniejsze (zwłaszcza, że nie ma zmiennych pośrednich tylko sekwencyjny ciąg wywołań; czyta się więc bez wracania, by sprawdzić co znaczą zmienne pośrednie) i trudniej się walnąć. Dodatkowo jednowyrażeniowe lambdy nie potrzebują słówka return więc go też możemy oszczędzić.

Niestety mapy nie mają metody getOptional, więc trzeba zaimportować ją z Optionala i zamiast:

mapa.getOptional(key);

będzie:

ofNullable(mapa.get(key):
0

@Wibowit:
Powiem szczerze, że ja JDK 1.8 na produkcji dość rzadko widuje w poważnych projektach (z oczywistych względów, jest młode, a migracje są ryzykowne). Odnoszę wrażenie, że lambdy skracają kod (co często jest ok). Jednak złożoność problemu wciąż zostaje. I wciąż należy być ostrożnym (np. pisać unit testy analogicznie jak do ifków sprawdzających co zrobić, gdy w przypadku nieodnalezienia wartości w mapie wartość domyślna została ustawiona), ponieważ złożoność wciąż pozostaje, po prostu zostaje inaczej upakowana.

0

Złożoność problemu nie polega na tym jak sobie z nullem poradzić, tylko gdzie się nulla spodziewać. Jeżeli nie używasz Optionali to musisz np używać adnotacji Nullable, NonNullable, itp by sobie oznaczyć w kodzie co może być nullem, a co nie.

Patrząc na linijki kodu z wywołaniami metod widzisz tylko to. Nie widzisz komentarzy do nich, ani testów do nich. Możesz oczywiście do nich za każdym razem zaglądać, aż zapamiętasz cały kod aplikacji na blachę, ale to na pewno nie będzie profesjonalne podejście. Używanie Optionala połączone ze statycznym systemem typów daje właśnie to, że od razu z kodu widać gdzie można spodziewać się pustej wartości. Mało tego - na Optionalu operuje się za pomocą jego metod, więc nawet przypadkowe napisanie kodu wywalającego NPE będzie trudniejsze, bo wywołanie metody get() na Optionalu się samo nie pisze.

0

@Wibowit
No tak, w tej chwili korzystając z zewnętrznego API często trzeba było patrzeć np. w JavaDoc / kod jakie są zwracane wartości. I tak trzeba bedzie to robic, bo wiele bibliotek musi byc kompatybilnych wstecz (i dobrze, witamy w prawdziwym swiecie). Dobrze, ze w JDK 1.8 to wprowadzili. Jest szansa, ze nowe API beda czytelniejsze. Dzieki za rzeczowa odpowiedz.

1 użytkowników online, w tym zalogowanych: 0, gości: 1