konto usunięte

Temat: Porównanie Stringów

Witam!
W Javie programuje od wczoraj. I mam problem, na który nadal nie znalazłem odpowiedzi (ale będę szukał).
Robię porównanie:
if (json_hash.get("success") == "1") {}
gdzie wcześniej wyświetlam element HashMap i jest równy "1". Wykonuje się jednak to, co jest w else.
Co mogę robić źle?
Pozdrawiam: J

konto usunięte

Temat: Porównanie Stringów

... a googlałeś w ogóle? Bo gdybyś probował, to by Ci wyszło, że porównujesz nie stringi, ale ich referencje. Do porównywania jest metoda Object.equals() albo String.equalsIgnoreCase():

if ( "1".equals(json_hash.get("success") ) ) {
}

czemu "1".equals a nie get("asd").equals? Bo jak get zwróci nulla, to będzie wyjątek.Dariusz Wawer edytował(a) ten post dnia 12.04.13 o godzinie 09:14

konto usunięte

Temat: Porównanie Stringów

Dziękuję bardzo :)
Oczywiście, że googlowałem. Ale po programowaniu w PHP/Pythonie takie rzeczy nie są oczywiste.
Musze nastawić się na to, że w Javie programuje się zupełnie inaczej niż w znanych mi językach.
Pozdrawiam i jeszcze raz dziękuję :)

konto usunięte

Temat: Porównanie Stringów

wpisałem temat twojego posta + Java w google, czyli "java porównywanie stringów". Pierwsze kilka wyników opisuje dokładnie to co trzeba.

konto usunięte

Temat: Porównanie Stringów

W takim razie przepraszam za zawracanie głowy. Postaram się lepiej rozumieć to, co pokazuje mi google :)

konto usunięte

Temat: Porównanie Stringów

ja proponuję klasę StringUtils z pakietu apache-commons.
Maciej Nowicki

Maciej Nowicki Java Developer

Temat: Porównanie Stringów

Darek Z.:
ja proponuję klasę StringUtils z pakietu apache-commons.

Jak to się mówi "do wszystkie o czym pomyślisz są jakieś commonsy" ;) ale na początek sugerowałbym poznanie podstaw programowania w Javie i poczytanie na serio jakiejś książki. Bo jak zaczniesz robić coś większego w momencie kiedy Stringi chcesz porównać przez ==, możesz narobić więcej szkód niż pożytku.

konto usunięte

Temat: Porównanie Stringów

Mam zamiar się dokształcić :)

konto usunięte

Temat: Porównanie Stringów

Darek Z.:
ja proponuję klasę StringUtils z pakietu apache-commons.
a można wiedzieć po co ściągać kolejne biblioteki żeby porównywać Stringi ?

konto usunięte

Temat: Porównanie Stringów

Apache-Commons to nie tylko porównywanie Stringów, zawiera więcej ciekawych klas. A dlaczego akurat użyć StringUtils? Bo to zawsze łatwiej, choćby nie trzeba myśleć o NPE (np. optionSelected.equals(SAVE_OPTION) , gdzie optionSelected będzie null), używając StringUtils dostaniesz false. używając zwykłego porównania NPE.
Jarosław Szczepankiewicz

Jarosław Szczepankiewicz Lead Technical
Consultant

Temat: Porównanie Stringów

Darek Z.:
Apache-Commons to nie tylko porównywanie Stringów, zawiera więcej ciekawych klas. A dlaczego akurat użyć StringUtils? Bo to zawsze łatwiej, choćby nie trzeba myśleć o NPE (np. optionSelected.equals(SAVE_OPTION) , gdzie optionSelected będzie null), używając StringUtils dostaniesz false. używając zwykłego porównania NPE.

dlatego zalecaną metodą porównywania zmiennej do stałej jest

STAŁA.equals(referencjaKtóraMozeByCNullem)

tak jak wczesniej koledzy polecam wpierw refleksję przed ściąganiem i używaniem bibliotek do prostych rzeczy dostępnych w samym języku.
Adrian C.

Adrian C.
projektant/programis
ta

Temat: Porównanie Stringów

Jarosław S.:
Darek Z.:
Apache-Commons to nie tylko porównywanie Stringów, zawiera więcej ciekawych klas. A dlaczego akurat użyć StringUtils? Bo to zawsze łatwiej, choćby nie trzeba myśleć o NPE (np. optionSelected.equals(SAVE_OPTION) , gdzie optionSelected będzie null), używając StringUtils dostaniesz false. używając zwykłego porównania NPE.

dlatego zalecaną metodą porównywania zmiennej do stałej jest

STAŁA.equals(referencjaKtóraMozeByCNullem)

tak jak wczesniej koledzy polecam wpierw refleksję przed ściąganiem i używaniem bibliotek do prostych rzeczy dostępnych w samym języku.

Gizzz, przeczytałem słowo refleksja i już myślałem że chcecie poradzić koledze porównywanie Srtingów przez refleksję ;), idę na kawę...

konto usunięte

Temat: Porównanie Stringów

Jarosław S.:
dlatego zalecaną metodą porównywania zmiennej do stałej jest

STAŁA.equals(referencjaKtóraMozeByCNullem)

Jest na to termin: "Yoda conditions":

http://tinyurl.com/cgb6f4f
Wiktor S.

Wiktor S. Developer |
Konsultant | Trener

Temat: Porównanie Stringów

Jarosław S.:

dlatego zalecaną metodą porównywania zmiennej do stałej jest

STAŁA.equals(referencjaKtóraMozeByCNullem)

Ogólniej rzecz biorąc jest to jedna z technik "programowania defensywnego".
Polecam przyjrzenie się tematowi, zaczynając choćby od angielskiej wiki http://en.wikipedia.org/wiki/Defensive_programming

Temat: Porównanie Stringów

Jak już mówimy o stylu codu, to mamy tu piękny przyklad "stringly typed application" :-))
gdzie logika programu opiera się na porównywaniu stringów.
Marcin Mroczkowski

Marcin Mroczkowski Programista JAVA/JEE

Temat: Porównanie Stringów

Trochę schodzimy na offtop, ale taka konstrukcja wcale nie jest najlepszym sposobem na pozbycie się NPE. Jeśli używamy tego w wewnętrznej logice to sami prosimy się o problemy.
Dla przykładu logika napisana w taki sposób:

if ("NORMAL".equals(status)) {
// dla statusu normalnego coś robimy
}

Na pierwszy rzut oka wygląda zwięźle i prosto. Zwykłe testy też przejdą bez zająknięcia. Problem w tym że ta logika jest dziurawa i taki kod wcześniej, czy później wbije nam nóż w plecy.

Hipotetyczna sytuacja - ktoś rozbudowuje ORM aplikacji i popełnia błąd w mapowaniu kolumn. String "status" staje się nullem, a nasza funkcja beztrosko go przetwarza, propagując błąd dalej. Bez solidnego teamu testerskiego taki bug może z powodzeniem wejść na produkcję, a my po tygodniu budzimy się z krytycznym błędem i tysiącem uszkodzonych obiektów, a log błędów... jest całkowicie czysty. Takie zachowanie aplikacji to Mad Girlfriend Bug:
http://www.codinghorror.com/blog/2012/07/new-programmi...

Jeśli funkcja jest zapisana bez użycia tej konstrukcji to developer dostaje NPE, poprawia to w 10 min, a problem nie wychodzi poza komputer programisty. Taki styl pisania jest promowany w całym JDK, dostarczając w wymaganym parametrze null do funkcji zwykle dostajemy NPE. Sun nie pisał tego z potrzeby bycia złośliwym, tylko tak po prostu szybciej wykrywa się błędy.
http://en.wikipedia.org/wiki/Fail-fast

Podsumowując, moim zdaniem można tego użyć jako skrót w walidacji niepewnego wejścia(np. input użytkownika), ale nigdy jako "rekomendowany" sposób porównywania stringów.

Temat: Porównanie Stringów

Słuszne spostrzeżenie Marcinie.
Pozwolę sobie przy okazji przedstawić moją, alternatywną strategię polegającą na połączeniu Yoda Conditions z elementami programowania kontraktowego (http://pl.wikipedia.org/wiki/Programowanie_kontraktowe).

Dobrze wiemy, że nie wszystkie wartości są zawsze wymagane.
Stosowanie konwencji odwrotnej do proponowanej w przypadku wartości której wartość null jest dozwolona doprowadzi do konieczności 'zasadzania' checknulli w kodzie.
Stosowanie konwencji STAŁA.equals(..) dla wartości które mogą być puste oraz zmienna.equals(STAŁA) dla tych które mają zawsze być nie puste jest mało przejrzyste i będzie powodować wiele pomyłek.

Dlatego osobiście preferuję Yoda conditions + warunki początkowe.
Pole jest wymagane, a brak jego wartości oznacza błąd?
Sprawdzam to na początku metody i w razie czego rzucam NPE. Akurat w projekcie korzystamy już z Guavy, więc zamiast wymyślać koło od nowa sięgam po ichniejsze Preconditions (http://code.google.com/p/guava-libraries/wiki/Precondi....

Moim zdaniem łatwiej jest wtedy wyłapać warunki dot. atrybutów metody / stanu obiektu oraz dzięki temu, że mogę ustawić własny message dla wyjątku jest on bardziej użyteczny (za X czasu nie będę pamiętał czy w klasce XYZ w linii 35 robiłem equals na argumencie A czy B). Nie zawsze trzeba zaglądać do źródeł by zrozumieć błąd, no i zabezpieczamy się przed zignorowaniem takiego błędu przez LogDigger oraz nie wysłaniu go na issue tracker ale to już zupełnie inny temat ;)

Bynajmniej nie uważam, żeby to była jakaś jedyna słuszna konwencja - po prostu taki sposób dziś mi odpowiada.Marcin Kubala edytował(a) ten post dnia 25.04.13 o godzinie 11:36
Marcin Mroczkowski

Marcin Mroczkowski Programista JAVA/JEE

Temat: Porównanie Stringów

Programowanie kontraktowe bardzo pozytywnie wpływa na niezawodność kodu, ale ma jeden poważny problem - wprowadza dużo boilerplate do kodu biznesowego. Powoduje to rozrzucenie aspektu walidacji po wielu metodach i ich bardzo możliwą duplikację.
Moim zdaniem najlepsze rozwiązanie proponuje szkoła domain driven design (oczywiście chodzi nadal o kod domeny). Podejście "always valid" zakłada, że dane wewnątrz warstwy biznesowej są zawsze poprawne i nie na sensu ich sprawdzać. Tutaj jest fajnie rozważanie na ten temat:
http://gorodinski.com/blog/2012/05/19/validation-in-do...

Po prostu programujesz logikę z pominięciem walidacji i technikaliów języka (z NPE włącznie) zakładając, że dane są zawsze poprawne. Dzięki temu kod w środku jest czystą reprezentacją idei biznesowych nie zlepkiem wielu aspektów w jednym miejscu.

Walidacja wyciągnięta jest wtedy poza obiekty biznesowe i przeprowadzana gdzie indziej np. w fabrykach obiektów, serwisach, czy repozytoriach. Mechanizmy te troszczą się o to, żeby nieprawidłowy obiekt nie powstał nigdy.

Jeszcze odnośnie yoda conditions, prywatnie nie stosuje tego, ponieważ nie jest to zgodne ze standardowym kierunkiem myślenia i może być trochę nieczytelne/dziwne dla ludzi, którzy będą później taki kod utrzymywać. Ale tak jak mówisz, każdy ma swój styl, a każdy styl ma plusy i minusy, to jak spierać się czy niebieski jest ładniejszy od zielonego :)Marcin Mroczkowski edytował(a) ten post dnia 25.04.13 o godzinie 15:49

konto usunięte

Temat: Porównanie Stringów

Jesli chodzi o gołą Jave: od pierwszego wejrzenia "zaprzyjaźniłem się" z Objects.requireNotNull() z Java 7

public Foo(Bar bar, Baz baz) {
this.bar = Objects.requireNonNull(bar, "bar must not be null");
this.baz = Objects.requireNonNull(baz, "baz must not be null");
}


Już teraz oszczędziła mi sporo czasu - jak kiedyś szukaliście skąd sie wziął NPE, to wiecie o czym mówię :-)

Temat: Porównanie Stringów

Wróćmy do oryginalnego problemu.

Zauważmy, że w programie istnieje konwencja, że pseudo-zmienna 'success' ma wartość "1" w przypadku sukcesu. Nie wiemy czy jeżeli ta pseudo-zmienna jest null to czy jest to wyjątek, czy normalna sytuacja, gdy jakaś operacja jsona'a się nie powiodła.

Swoją drogą warto rozdzielać parsowanie stringów i konwencje od logiki.

np.:

boolean success = parseSuccessStatus(jsonHash);
if (success) {

}

lub:

int status = parseSuccessStatus(jsonHash);
switch (status) {
case 0:
case 1:
case 2:
}

zamiast int'a powienien byc w zasadzie odpowiedni enum



Wyślij zaproszenie do