Podczas testowania równości String
w Javie zawsze używałem, equals()
ponieważ wydaje mi się, że jest to najbardziej naturalna metoda. W końcu jego nazwa już mówi, co ma zrobić. Jednak mój kolega niedawno powiedział mi, że nauczono mnie używać compareTo() == 0
zamiast equals()
. Wydaje mi się to nienaturalne (co compareTo()
ma na celu zapewnienie porządku, a nie porównywanie dla równości), a nawet trochę niebezpieczne (ponieważ compareTo() == 0
niekoniecznie oznacza to równość we wszystkich przypadkach, chociaż wiem, że tak String
jest dla mnie).
Nie wiedział, dlaczego nauczono go używać compareTo()
zamiast equals()
for String
, a ja też nie mogłem znaleźć żadnego powodu dlaczego. Czy to naprawdę kwestia osobistego gustu, czy też istnieje prawdziwy powód dla którejkolwiek z metod?
.equalsIgnoreCase()
jest najszybszym porównaniem, jeśli jest właściwe, w przeciwnym razie.equals()
jest to, czego chcesz.compareTo() == 0
niekoniecznie oznacza równość we wszystkich przypadkach”. To jest absolutnie poprawne! Dokładnie to oznacza wyrażenie „zgodne z równymi” w specyfikacji interfejsu API języka Java, na przykład w specyfikacji klasy Comparable . Na przykład metoda porównania String jest zgodna z równymi, ale metoda porównania BigDecimal jest niespójna z równymi.Odpowiedzi:
Różnica polega na tym, że
"foo".equals((String)null)
zwraca wartość false, gdy"foo".compareTo((String)null) == 0
zgłasza wyjątek NullPointerException. Więc nie zawsze są wymienne, nawet w przypadku Strings.źródło
Dwie główne różnice to:
equals
weźmie dowolny obiekt jako parametr, alecompareTo
tylko ciągi.equals
mówi tylko o tym, czy są równe, czy nie, alecompareTo
daje informacje o tym, jak Ciągi są porównywane leksykograficznie.Wziąłem okiem na kod klasy String , a algorytm w CompareTo i wynosi wygląda w zasadzie tak samo. Uważam, że jego opinia była tylko kwestią gustu i zgadzam się z tobą - jeśli wszystko, co musisz wiedzieć, to równość Strun, a nie to, która z nich jest leksykograficzna jako pierwsza, użyłbym
equals
.źródło
Porównując pod kątem równości, powinieneś używać
equals()
, ponieważ wyraża to twoje intencje w jasny sposób.compareTo()
ma tę dodatkową wadę, że działa tylko na obiektach implementującychComparable
interfejs.Dotyczy to ogólnie, nie tylko dla Strings.
źródło
compareTo
musi wykonać więcej pracy, jeśli struny mają różne długości.equals
może po prostu zwrócić wartość false, podczas gdycompareTo
zawsze musi sprawdzić wystarczającą liczbę znaków, aby znaleźć porządek sortowania.źródło
compareTo()
dotyczy nie tylko ciągów znaków, ale także każdego innego obiektu, ponieważcompareTo<T>
przyjmuje argument ogólnyT
. String jest jedną z klas, która zaimplementowałacompareTo()
metodę poprzez implementacjęComparable
interfejsu. (compareTo () jest metodą dla porównywalnego interfejsu). Więc każda klasa może zaimplementować interfejs porównywalny.Ale
compareTo()
podaje porządek obiektów , używany zwykle do sortowania obiektów w porządku rosnącym lub malejącym, podczas gdyequals()
mówi tylko o równości i mówi, czy są równe, czy nie.źródło
W kontekście ciągów:
compareTo: porównuje dwa ciągi leksykograficznie.
equals: porównuje ten ciąg z określonym obiektem.
CompareTo porównuje dwa ciągi według ich znaków (w tym samym indeksie) i odpowiednio zwraca liczbę całkowitą (dodatnią lub ujemną).
źródło
Bardzo ważna różnica między compareTo i equals:
equals () sprawdza, czy dwa obiekty są takie same, czy nie, i zwraca wartość logiczną.
compareTo () (z interfejsu Comparable) zwraca liczbę całkowitą. Sprawdza, który z dwóch obiektów jest „mniejszy niż”, „równy” lub „większy od” drugiego. Nie wszystkie obiekty można logicznie uporządkować, więc metoda compareTo () nie zawsze ma sens.
Zauważ, że equals () nie definiuje kolejności między obiektami, co robi metoda compareTo ().
Teraz radzę ci przejrzeć kod źródłowy obu metod, aby stwierdzić, że równa się jest lepsza niż metoda compareTo, która wymaga pewnych obliczeń matematycznych.
źródło
Wygląda na to, że obie metody robią prawie to samo, ale metoda compareTo () pobiera String, a nie Object, i dodaje dodatkowe funkcje do normalnej metody equals (). Jeśli zależy ci tylko na równości, to metoda equals () jest najlepszym wyborem, po prostu dlatego, że ma więcej sensu dla następnego programisty, który przyjrzy się Twojemu kodowi. Różnica czasu między dwiema różnymi funkcjami nie powinna mieć znaczenia, chyba że przeglądasz ogromną liczbę elementów. Funkcja compareTo () jest naprawdę przydatna, gdy trzeba znać kolejność ciągów w kolekcji lub gdy trzeba poznać różnicę w długości między ciągami zaczynającymi się od tej samej sekwencji znaków.
źródło: http://java.sun.com/javase/6/docs/api/java/lang/String.html
źródło
equals()
powinna być metodą z wyboru w przypadku PO.Patrząc na implementację
equals()
icompareTo()
w java.lang.String w grepcode , możemy łatwo zauważyć, że equals jest lepsze, jeśli interesuje nas tylko równość dwóch ciągów:equals()
:i
compareTo()
:Kiedy jeden z ciągów jest prefiksem innego, wydajność
compareTo()
jest gorsza, ponieważ nadal musi określić kolejność leksykograficzną,equals()
nie martwiąc się więcej i natychmiast zwraca false.Moim zdaniem powinniśmy używać tych dwóch zgodnie z przeznaczeniem:
equals()
aby sprawdzić równość icompareTo()
znaleźć porządek leksykalny.źródło
equals () sprawdza, czy dwa łańcuchy są równe, czy nie i zwraca wartość logiczną. CompareTo () sprawdza, czy obiekt string jest równy, większy lub mniejszy od innego obiektu typu string i daje wynik jako: 1 jeśli obiekt string jest większy 0 jeśli oba są równe -1 jeśli łańcuch jest mniejszy niż inny ciąg
eq:
źródło
Są pewne rzeczy, o których musisz pamiętać podczas zastępowania funkcji compareTo w Javie, np. Compareto musi być spójne z równościami, a odejmowanie nie powinno być używane do porównywania pól całkowitych, ponieważ mogą się przepełniać. Aby uzyskać szczegółowe informacje, sprawdź Rzeczy do zapamiętania podczas zastępowania komparatora w Javie .
źródło
To jest eksperyment z nekromancją :-)
Większość odpowiedzi dotyczy porównania wydajności i różnic w API. Pomijają podstawowy punkt, że te dwie operacje mają po prostu różną semantykę.
Twoja intuicja jest poprawna. x.equals (y) nie jest wymienne z x.compareTo (y) == 0. Pierwsza porównuje tożsamość, podczas gdy druga porównuje pojęcie „rozmiar”. Prawdą jest, że w wielu przypadkach, zwłaszcza w przypadku typów prymitywnych, te dwa elementy są dopasowane.
Ogólny przypadek jest taki:
Jeśli x i y są identyczne, mają ten sam `` rozmiar '': jeśli x.equals (y) jest prawdą => x.compareTo (y) wynosi 0.
Jeśli jednak x i y mają ten sam rozmiar, nie oznacza to, że są identyczne.
jeśli x.compareTo (y) jest równe 0, niekoniecznie oznacza, że x.equals (y) jest prawdą.
Niezwykłym przykładem, w którym tożsamość różni się od rozmiaru, byłyby liczby zespolone. Załóżmy, że porównanie jest dokonywane według ich wartości bezwzględnej. A więc biorąc pod uwagę dwie liczby zespolone: Z1 = a1 + b1 * i oraz Z2 = a2 + b2 * i:
Z1.equals (z2) zwraca prawdę wtedy i tylko wtedy, gdy a1 = a2 i b1 = b2.
Jednak Z1.compareTo (Z2) zwraca 0 dla i nieskończoną liczbę par (a1, b1) i (a2, b2), o ile spełniają warunek a1 ^ 2 + b1 ^ 2 == a2 ^ 2 + b2 ^ 2.
źródło
Równość może być bardziej wydajna niż metoda compareTo.
Jeśli długość sekwencji znaków w łańcuchu nie pasuje, nie ma możliwości, aby ciągi były równe, więc odrzucenie może być znacznie szybsze.
Co więcej, jeśli jest to ten sam przedmiot (równość tożsamości, a nie równość logiczna), będzie również bardziej wydajna.
Gdyby również zaimplementowali buforowanie hashCode, odrzucenie wartości różnej od równości mogłoby być jeszcze szybsze w przypadku, gdy ich hashCode nie pasuje.
źródło
String.equals()
wymaga wywołaniainstanceof
operatora, podczas gdycompareTo()
nie wymaga. Mój kolega zauważył duży spadek wydajności spowodowany nadmierną liczbąinstanceof
wywołańequals()
metody, jednak mój test okazałcompareTo()
się tylko nieznacznie szybszy.Używałem jednak Javy 1.6. W innych wersjach (lub u innych dostawców JDK) różnica może być większa.
W teście porównano każdy ciąg znaków w 1000-elementowych tablicach, powtórzonych 10 razy.
źródło
compareTo()
jest szybszy niżequals()
? Ale w przypadku większości zestawów danych ze świata rzeczywistegoequals()
jest znacznie szybszy niżcompareTo() == 0
.equals()
świeci, jeśli łańcuchy mają wspólny przedrostek, ale różne długości lub jeśli są w rzeczywistości tym samym obiektem.equals
może przyjąć dowolny obiekt jako parametr, alecompareTo
może przyjąć tylko wartość String.gdy cometo null,
compareTo
zgłosi wyjątekjeśli chcesz wiedzieć, gdzie występuje różnica, możesz użyć
compareTo
.źródło
equals
: wymagane do sprawdzania równości i ograniczania duplikatów. Wiele klas biblioteki Java korzysta z tego w przypadku, gdy chcą znaleźć duplikaty. np.HashSet.add(ob1)
doda tylko wtedy, gdy to nie istnieje. Więc jeśli rozszerzasz niektóre klasy, takie jak ta, zastąpequals()
.compareTo
: wymagane do zamówienia elementu. Ponownie do stabilnego sortowania potrzebujesz równości, więc jest zwrot 0.źródło
Równa się -
1 - Zastąp metodę GetHashCode, aby umożliwić poprawne działanie typu w tabeli skrótów.
2- Nie zgłaszaj wyjątku w implementacji metody Equals. Zamiast tego zwróć false dla pustego argumentu.
3-
Kolejne wywołania x.Equals (y) zwracają tę samą wartość, o ile obiekt, do którego odwołuje się x i y, nie jest modyfikowany.
4- W przypadku niektórych rodzajów obiektów pożądane jest, aby zamiast równości referencyjnej mieć test równości pod kątem równości wartości. Takie implementacje Equals zwracają wartość true, jeśli dwa obiekty mają tę samą wartość, nawet jeśli nie są tym samym wystąpieniem.
Na przykład -
Wynik :-
podczas porównywania do -
Porównuje bieżące wystąpienie z innym obiektem tego samego typu i zwraca liczbę całkowitą wskazującą, czy bieżące wystąpienie poprzedza, następuje po nim, czy występuje w tej samej pozycji w kolejności sortowania co inny obiekt.
Wraca -
Mniejsze niż zero - to wystąpienie poprzedza obj w kolejności sortowania. Zero - to wystąpienie występuje w tej samej pozycji w kolejności sortowania co obj. Większe niż zero - to wystąpienie następuje po obj w kolejności sortowania.
Może zgłosić ArgumentException, jeśli obiekt nie jest tego samego typu co wystąpienie.
Na przykład możesz odwiedzić tutaj.
Dlatego sugeruję, aby lepiej użyć Equals zamiast compareTo.
źródło
GetHashCode()
metody. Czy masz na myślihashCode()
?„równa się” porównuje obiekty i zwraca prawdę lub fałsz, a „porównaj z” zwraca 0, jeśli jest prawdą lub liczbą [> 0] lub [<0], jeśli jest fałszem. Oto przykład:
Wyniki:
Dokumentacja Porównaj z: https://docs.oracle.com/javase/7/docs/api/java/lang/Comparable.html
Dokumentacja równa się: https://docs.oracle.com/javase/7/docs/api/java/lang/Object.html#equals(java.lang.Object)
źródło
Tutaj jedna rzecz jest ważna podczas używania
compareTo()
over,equals()
którycompareTo
działa dla klas, które implementują interfejs `` Porównywalny '', w przeciwnym razie wyrzuci plikNullPointerException
.String
klasy implementują porównywalny interfejs, podczas gdyStringBuffer
nie można go używać"foo".compareTo("doo")
wString
obiekcie, ale nie wStringBuffer
Object.źródło
To wypisuje -2 i false
Wypisuje 2 i false
To wypisuje 0 i prawda
equals zwraca wartość logiczną wtedy i tylko wtedy, gdy oba ciągi są zgodne.
Funkcja compareTo ma nie tylko powiedzieć, czy pasują, ale także powiedzieć, który ciąg jest mniejszy od drugiego, a także o ile, leksykograficznie. Jest to używane głównie podczas sortowania w kolekcji.
źródło
Uważam
equals
iequalsIgnoreCase
metodyString
zwrotutrue
ifalse
co jest przydatne, jeśli chcesz porównać wartości obiektu typu string, ale w przypadku implementacjicompareTo
icompareToIgnoreCase
metod zwraca wartość dodatnią, ujemną i zerową, co będzie przydatne w przypadku sortowania.źródło