Chciałem wyjaśnić, czy dobrze to rozumiem:
==
jest porównaniem odniesienia, tzn. oba obiekty wskazują to samo miejsce w pamięci.equals()
ocenia do porównania wartości w obiektach
java
identity
equality
object-comparison
brainydexter
źródło
źródło
.equals()
jak sensownie odpowiednikOdpowiedzi:
Zasadniczo odpowiedź na twoje pytanie brzmi „tak”, ale ...
.equals(...)
porówna tylko to, co napisano do porównania, nie więcej, nie mniej.equals(Object o)
metoda najbliższej klasy nadrzędnej, która zastąpiła tę metodę.Object#equals(Object o)
metoda. Dla interfejsu API obiektu jest to to samo, co==
; to znaczy zwraca prawdę wtedy i tylko wtedy, gdy obie zmienne odnoszą się do tego samego obiektu, jeśli ich odwołania są takie same. W ten sposób będziesz testować równość obiektów, a nie równość funkcjonalną .hashCode
jeśli nadpisujesz,equals
aby nie „zerwać kontraktu”. Zgodnie z interfejsem API wynik zwracany zhashCode()
metody dla dwóch obiektów musi być taki sam, jeśli ichequals
metody wykazują, że są one równoważne. Odwrotna sytuacja nie musi być prawdą.źródło
==
sprawdza referencje pamięci, to dlaczego otrzymuję to dziwne zachowanie w [this] [1] [1]: docs.google.com/document/d/… Spodziewałem się, że dane wyjściowe będą prawdziwe. mogę usunąć moje nieporozumieniaThe equals method for class Object implements the most discriminating possible equivalence relation on objects; that is, for any non-null reference values x and y, this method returns true if and only if x and y refer to the same object (x == y has the value true).
<br/>Note that it is generally necessary to override the hashCode method whenever this method is overridden, so as to maintain the general contract for the hashCode method, which states that equal objects must have equal hash codes.
( docs.oracle.com/javase/7/docs/api/java/lang/… )W odniesieniu do klasy String:
Równości () Sposób porównuje „wartość” wewnątrz przypadkach łańcuch znaków (na hałdy), niezależnie, czy dwa odniesienia obiektów odnoszą się do tego samego przykładu łańcuchach lub nie. Jeśli jakieś dwa odwołania do obiektów typu String odnoszą się do tej samej instancji String, to świetnie! Jeśli dwa odwołania do obiektów odnoszą się do dwóch różnych instancji String ... nie robi to różnicy. Jest to „wartość” (to znaczy zawartość tablicy znaków) w każdej porównywanej instancji String.
Z drugiej strony operator „==” porównuje wartość dwóch odwołań do obiektów, aby sprawdzić, czy odnoszą się one do tej samej instancji String . Jeśli wartość obu odwołań do obiektów „odnosi się” do tej samej instancji String, wynikiem wyrażenia logicznego byłoby „true” .. duh. Jeśli natomiast wartość obu odwołań do obiektów „odnosi się” do różnych instancji String (mimo że obie instancje String mają identyczne „wartości”, to znaczy zawartość tablic znaków każdej instancji String jest taka sama), wynikiem wyrażenia logicznego byłoby „fałsz”.
Jak w przypadku każdego wyjaśnienia, pozwól mu się zanurzyć.
Mam nadzieję, że to trochę wyjaśni.
źródło
String
s,==
odniesienie jest również równe, tak, ale zwykle działa (jak w dwóchString
sekundach z tą samą zawartością zwykle będą==
do siebie), z powodu tego, jak Java obsługujeString
s. Nie zawsze będzie to z pewnością zła praktyka, ale jest to powszechny błąd, szczególnie wśród osób pochodzących z innych języków.String
build z literału łańcuchowego zostanie dodany do czegoś zwanegoString constant pool
np.String s1 = "someString"; String s2 = "someString;"
obas1
is2
będą dzielić to samo odwołanie.s1 == s2
zwróci prawdę. Ale jeśli zostały zbudowaneString constructor
np.String s1 = new String("someString"); String s2 = new String("someString");
, To nie będą dzielić tego samego odniesienia.s1 == s2
zwróci fałsz.Istnieją niewielkie różnice w zależności od tego, czy mówimy o „prymitywach”, czy „typach obiektów”; to samo można powiedzieć, jeśli mówimy o członkach „statycznych” lub „niestatycznych”; możesz także wymieszać wszystkie powyższe ...
Oto przykład (możesz go uruchomić):
Możesz porównać objaśnienia dla „==” (operator równości) i „.equals (...)” (metoda w klasie java.lang.Object) za pomocą tych łączy:
źródło
Różnica między == i równa mi się przez jakiś czas myliła, dopóki nie zdecydowałem się przyjrzeć jej bliżej. Wielu z nich twierdzi, że do porównywania ciągów powinieneś używać,
equals
a nie używać==
. Mam nadzieję, że w tej odpowiedzi będę mógł powiedzieć różnicę.Najlepszym sposobem na udzielenie odpowiedzi na to pytanie będzie zadanie sobie kilku pytań. a więc zacznijmy:
Jakie są dane wyjściowe dla poniższego programu:
Jeśli powiesz,
Powiem, że masz rację, ale dlaczego to powiedziałeś ? a jeśli powiesz, że wynik jest
Powiem, że się mylisz, ale wciąż będę cię pytać, dlaczego uważasz, że tak jest?
Ok, spróbujmy odpowiedzieć na to:
Jakie są dane wyjściowe dla poniższego programu:
Teraz, jeśli powiesz,
Powiem, że się mylisz, ale dlaczego teraz się mylisz ? poprawne wyjście dla tego programu to
Porównaj powyższy program i spróbuj o tym pomyśleć.
Ok. Teraz to może pomóc (przeczytaj to: wydrukuj adres obiektu - nie jest to możliwe, ale nadal możemy go używać).
czy możesz po prostu pomyśleć o wynikach trzech ostatnich wierszy powyższego kodu: dla mnie ideone wydrukował to ( możesz sprawdzić kod tutaj ):
O! Teraz widzisz tożsamośćHashCode (mango) jest równa identycznościHashCode (mango2) Ale nie jest równa identycznościHashCode (mango3)
Mimo że wszystkie zmienne łańcuchowe - mango, mango2 i mango3 - mają tę samą wartość, czyli „mango”,
identityHashCode()
nadal nie jest taka sama dla wszystkich.Teraz spróbuj odkomentować tę linię
// mango2 = "mang";
i uruchom ją ponownie, tym razem zobaczysz wszystkie trzyidentityHashCode()
są różne. Hmm, to jest przydatna wskazówkawiemy, że jeśli
hashcode(x)=N
ihashcode(y)=N
=>x is equal to y
Nie jestem pewien, jak java działa wewnętrznie, ale zakładam, że tak się stało, kiedy powiedziałem:
java utworzyła ciąg,
"mango"
który został wskazany (przywołany) przez zmiennąmango
coś takiegoTeraz w następnym wierszu, kiedy powiedziałem:
W rzeczywistości użył ponownie tego samego ciągu,
"mango"
który wygląda mniej więcej takZarówno mango, jak i mango2 wskazują na to samo odniesienie Teraz, kiedy powiedziałem
W rzeczywistości stworzył zupełnie nowe odniesienie (ciąg znaków) dla „mango”. który wygląda mniej więcej tak
i dlatego, gdy podałem wartości dla
mango == mango2
, to zgasłotrue
. a kiedy wyłożyłem wartośćmango3 == mango2
, zgasłofalse
(nawet gdy wartości są takie same).a kiedy odkomentowałeś linię,
// mango2 = "mang";
faktycznie utworzył ciąg „mang”, który zmienił nasz wykres w ten sposób:To dlatego identyfikator tożsamości nie jest taki sam dla wszystkich.
Mam nadzieję, że to wam pomoże. Właściwie chciałem wygenerować przypadek testowy, w którym == kończy się niepowodzeniem i równa się () przejściu. Skomentuj i daj mi znać, jeśli się mylę.
źródło
mango == mango2
dzieje się tak, ponieważ nie utworzonomango2
nowego obiektu String, a zamiast tego bezpośrednio się do niego odwołuje"mango"
?Twoje zdrowie :-)
źródło
Będziesz musiał zastąpić funkcję równości (wraz z innymi), aby użyć jej z niestandardowymi klasami.
Metoda równa porównuje obiekty.
==
Operatora binarnego porównuje adresy pamięci.źródło
Zarówno ==, jak i .equals () odnoszą się do tego samego obiektu, jeśli nie zastąpisz .equals ().
To jest twoje życzenie, co chcesz zrobić, gdy zastąpisz .equals (). Możesz porównać stan obiektu wywołującego ze stanem obiektu przekazanego lub możesz po prostu wywołać super.equals ()
źródło
==
jest operatorem iequals()
jest metodą .Operatory są zwykle używane do pierwotnych porównań typów, dlatego
==
są używane do porównywania adresów pamięci, aequals()
metoda służy do porównywania obiektów .źródło
źródło
Pamiętaj tylko, że
.equals(...)
musi to zostać zaimplementowane przez klasę, którą próbujesz porównać. W przeciwnym razie nie ma większego sensu; wersja metody dla klasy Object robi to samo, co operacja porównania: Object # jest równy .Jedynym momentem, w którym naprawdę chcesz użyć operatora porównania dla obiektów, jest porównanie Enums. Jest tak, ponieważ istnieje tylko jedna instancja wartości Enum na raz. Na przykład biorąc pod uwagę wyliczenie
Nigdy nie będziesz mieć więcej niż jednego wystąpienia
A
naraz i to samo dlaB
iC
. Oznacza to, że możesz napisać taką metodę:I nie będziesz mieć żadnych problemów.
źródło
Kiedy oceniasz kod, jest bardzo jasne, że (==) porównuje według adresu pamięci, podczas gdy equals (Object o) porównuje hashCode () instancji. Dlatego mówi się, aby nie łamać umowy między equals () i hashCode (), jeśli później nie spotka Cię niespodzianka.
źródło
Oto ogólna zasada dotycząca różnicy między
relational operator ==
ithe method .equals()
.object1 == object2
porównuje, czy obiekty, do których odwołują się obiekty object1 i object2, odnoszą się do tej samej lokalizacji pamięci w Heap .object1.equals(object2)
porównuje wartości object1 i object2 niezależnie od tego, gdzie znajdują się w pamięci .Można to dobrze zademonstrować za pomocą String
Scenariusz 1
Scenariusz 2
To porównanie ciągów może być wykorzystane jako podstawa do porównania innych typów obiektów.
Na przykład, jeśli mam klasę Person , muszę zdefiniować podstawę kryteriów, na podstawie której porównam dwie osoby . Powiedzmy, że ta klasa osób ma zmienne instancji wzrostu i wagi.
Więc tworząc obiekty osoby
person1 and person2
i porównując te dwa za pomocą.equals()
I, muszę przesłonić metodę równości klasy person aby zdefiniować na podstawie zmiennych instancji (wysokość lub waga), jakie będzie porównanie.Jednak
== operator will still return results based on the memory location of the two objects(person1 and person2)
.Dla ułatwienia uogólnienia porównania obiektów tej osoby stworzyłem następującą klasę testową. Eksperymentowanie z tymi koncepcjami ujawni mnóstwo faktów .
Wynikiem wykonania tej klasy jest:
źródło
Zauważ też, że
.equals()
zwykle zawiera==
do testowania, ponieważ jest to pierwsza rzecz, którą chcesz przetestować, jeśli chcesz sprawdzić, czy dwa obiekty są równe.I
==
faktycznie sprawdza wartości dla typów pierwotnych, dla obiektów sprawdza referencje.źródło
== operator zawsze porównuje odniesienie. Ale w przypadku
to zależy od implementacji, jeśli mamy przesłoniętą metodę równości, niż porównuje obiekt z podstawową implementacją podaną w przesłoniętej metodzie.
w powyższym kodzie zarówno obiekt obj, jak i obiekt obj1 zawierają te same dane, ale odwołanie nie jest takie samo, więc równa się również false i ==. ale jeśli zastąpimy metodę równa się niż
Wiem, sprawdź, zwróci prawdę i fałsz w tym samym przypadku tylko my zastąpiliśmy
porównuje obiekt na podstawie podstawowej treści (id) obiektu
nadal porównuj odniesienia do obiektu.
źródło
Główną różnicą między == a equals () jest
1) == służy do porównywania prymitywów.
Na przykład :
2) equals () służy do porównywania obiektów. Na przykład :
źródło
==
można go używać w wielu typach obiektów, ale można go używaćObject.equals
w dowolnym typie, zwłaszcza w ciągach znaków i znacznikach mapy Google.źródło
---- Wyjście ----- prawda fałsz prawda
źródło
Warto dodać, że dla obiektów otoki dla typów pierwotnych - tj. Int, Long, Double - == zwróci true, jeśli obie wartości są równe.
Dla kontrastu, umieszczenie powyższych dwóch Longów w dwóch oddzielnych ArrayLists, równa się, widzi je tak samo, ale == nie.
źródło
Long a = 128l; Long b = 128l; System.out.println(a == b);
Basen String (aka interning ) i basen Integer rozmycie różnica dalej, i może pozwolić na wykorzystanie
==
obiektów w niektórych przypadkach zamiast.equals
Może to zapewnić większą wydajność (?), Kosztem większej złożoności.
Na przykład:
Kompromis złożoności: mogą Cię zaskoczyć:
Radzę trzymać się z dala od takiej mikrooptymalizacji i zawsze używać
.equals
do obiektów i==
do prymitywów:źródło
Krótko mówiąc, odpowiedź brzmi „tak”.
W Javie
==
operator porównuje dwa obiekty, aby sprawdzić, czy wskazują one na tę samą lokalizację pamięci; podczas gdy.equals()
metoda faktycznie porównuje dwa obiekty, aby sprawdzić, czy mają taką samą wartość obiektu.źródło
Zasadniczo
==
porównuje, jeśli dwa obiekty mają to samo odwołanie na stercie, więc jeśli dwa odniesienia nie zostaną połączone z tym samym obiektem, to porównanie będzie fałszywe.equals()
jest metodą odziedziczoną zObject
klasy. Ta metoda domyślnie porównuje, jeśli dwa obiekty mają to samo odniesienie. To znaczy:object1.equals(object2)
<=>object1 == object2
Jeśli jednak chcesz ustalić równość między dwoma obiektami tej samej klasy, powinieneś przesłonić tę metodę. Bardzo ważne jest również przesłonięcie metody,
hashCode()
jeśli przesłoniłeśequals()
.Wdrażaj,
hashCode()
gdy ustalanie równości jest częścią umowy Java Object Contract. Jeśli pracujesz z kolekcjami, a nie wdrożyłeśhashCode()
, mogą się zdarzyć dziwne złe rzeczy:null
zostanie wydrukowany po wykonaniu poprzedniego kodu, jeśli nie został zaimplementowanyhashCode()
.źródło
Ponieważ Java nie obsługuje przeciążania operatorów, == zachowuje się identycznie dla każdego obiektu, ale equals () jest metodą, którą można zastąpić w Javie, a logikę porównywania obiektów można zmieniać w oparciu o reguły biznesowe.
Główną różnicą między == i equals w Javie jest to, że „==” służy do porównywania prymitywów, a metoda equals () jest zalecana do sprawdzania równości obiektów.
Porównanie ciągów jest częstym scenariuszem używania metody == i równości. Ponieważ przesłonięcie klasy java.lang.String jest równe metodzie, Zwraca true, jeśli dwa obiekty String zawierają tę samą treść, ale == zwróci true tylko wtedy, gdy dwa odwołania wskazują na ten sam obiekt.
Oto przykład porównania dwóch ciągów w Javie pod kątem równości za pomocą metody == i equals (), które rozwieją pewne wątpliwości:
źródło