Ich wollte klarstellen, ob ich das richtig verstehe:
==
ist ein Referenzvergleich, dh beide Objekte zeigen auf denselben Speicherort.equals()
wertet den Vergleich der Werte in den Objekten aus
java
identity
equality
object-comparison
Brainydexter
quelle
quelle
.equals()
als sinnvoll gleichwertigAntworten:
Im Allgemeinen lautet die Antwort auf Ihre Frage "Ja", aber ...
.equals(...)
wird nur vergleichen, was geschrieben ist, um zu vergleichen, nicht mehr und nicht weniger.equals(Object o)
Methode der nächsten übergeordneten Klasse verwendet, die diese Methode überschrieben hat.Object#equals(Object o)
Methode behalten. Gemäß der Objekt-API ist dies dasselbe wie==
; Das heißt, es wird genau dann true zurückgegeben, wenn beide Variablen auf dasselbe Objekt verweisen, wenn ihre Referenzen ein und dasselbe sind. Sie testen also auf Objektgleichheit und nicht auf funktionale Gleichheit .hashCode
Sie immer daran, zu überschreiben, wenn Sie überschreibenequals
, um nicht "den Vertrag zu brechen". Gemäß der API muss das von derhashCode()
Methode für zwei Objekte zurückgegebene Ergebnis dasselbe sein, wenn ihreequals
Methoden zeigen, dass sie gleichwertig sind. Das Gegenteil ist nicht unbedingt der Fall.quelle
==
nach Speicherreferenzen gesucht wird, warum erhalte ich dann dieses seltsame Verhalten in [this] [1] [1]: docs.google.com/document/d/… Ich habe erwartet, dass die Ausgabe wahr ist. kann meine VerwirrungenThe 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/… )In Bezug auf die String-Klasse:
Die Methode equals () vergleicht den "Wert" in String-Instanzen (auf dem Heap), unabhängig davon, ob sich die beiden Objektreferenzen auf dieselbe String-Instanz beziehen oder nicht. Wenn zwei Objektreferenzen vom Typ String auf dieselbe String-Instanz verweisen, ist das großartig! Wenn sich die beiden Objektreferenzen auf zwei verschiedene String-Instanzen beziehen, macht dies keinen Unterschied. Es ist der "Wert" (dh der Inhalt des Zeichenarrays) in jeder String-Instanz, die verglichen wird.
Andererseits vergleicht der Operator "==" den Wert zweier Objektreferenzen , um festzustellen, ob sie sich auf dieselbe String-Instanz beziehen . Wenn der Wert beider Objektreferenzen auf dieselbe String-Instanz "verweist", wäre das Ergebnis des booleschen Ausdrucks "true". Duh. Wenn andererseits der Wert beider Objektreferenzen auf verschiedene String-Instanzen "verweist" (obwohl beide String-Instanzen identische "Werte" haben, dh der Inhalt der Zeichenarrays jeder String-Instanz gleich ist), ist der Ergebnis des booleschen Ausdrucks wäre "false".
Lassen Sie es wie bei jeder Erklärung einwirken.
Ich hoffe, das klärt die Dinge ein bisschen auf.
quelle
String
s,==
ist Referenz auch gleich, ja, aber es in der Regel funktioniert (wie in zweiString
s mit dem gleichen Inhalt wird in der Regel sein==
zueinander), weil, wie Java GriffeString
s. Es wird nicht immer und es ist sicherlich eine schlechte Praxis, aber es ist ein häufiger Fehler, insbesondere von Leuten, die aus anderen Sprachen kommen.String
Build aus String-Literal wird zu etwas hinzugefügt, das als " beide" bezeichnet wirdString constant pool
, z. B. " &" . wird true zurückgeben. Aber wenn sie über das konstruiert wurden , z. B. dann teilen sie nicht die gleiche Referenz. wird false zurückgeben.String s1 = "someString"; String s2 = "someString;"
s1
s2
s1 == s2
String constructor
String s1 = new String("someString"); String s2 = new String("someString");
s1 == s2
Es gibt einige kleine Unterschiede, je nachdem, ob es sich um "Grundelemente" oder "Objekttypen" handelt. Das Gleiche gilt, wenn Sie von "statischen" oder "nicht statischen" Mitgliedern sprechen. Sie können auch alle oben genannten mischen ...
Hier ist ein Beispiel (Sie können es ausführen):
Sie können die Erklärungen für "==" (Gleichheitsoperator) und ".equals (...)" (Methode in der Klasse java.lang.Object) über diese Links vergleichen:
quelle
Der Unterschied zwischen == und gleich verwirrte mich einige Zeit, bis ich mich entschied, es mir genauer anzusehen. Viele von ihnen sagen, dass Sie zum Vergleichen von Zeichenfolgen verwenden sollten
equals
und nicht==
. Hoffe auf diese Antwort kann ich den Unterschied sagen.Der beste Weg, um diese Frage zu beantworten, besteht darin, sich selbst ein paar Fragen zu stellen. so lass uns anfangen:
Was ist die Ausgabe für das folgende Programm:
wenn du sagst,
Ich werde sagen, dass Sie Recht haben, aber warum haben Sie das gesagt ? und wenn Sie sagen, die Ausgabe ist,
Ich werde sagen, dass Sie falsch liegen, aber ich werde Sie trotzdem fragen, warum Sie das für richtig halten.
Ok, lass uns versuchen, diese Frage zu beantworten:
Was ist die Ausgabe für das folgende Programm:
Wenn Sie jetzt sagen,
Ich werde sagen, dass Sie falsch liegen, aber warum ist es jetzt falsch ? Die richtige Ausgabe für dieses Programm ist
Bitte vergleichen Sie das obige Programm und versuchen Sie darüber nachzudenken.
OK. Dies könnte nun helfen (bitte lesen Sie dies: Drucken Sie die Adresse des Objekts aus - nicht möglich, aber wir können es trotzdem verwenden.)
Können Sie einfach versuchen, über die Ausgabe der letzten drei Zeilen im obigen Code nachzudenken? Für mich hat ideone dies ausgedruckt ( Sie können den Code hier überprüfen ):
Oh! Jetzt sehen Sie, dass der IdentityHashCode (Mango) gleich dem IdentityHashCode (Mango2) ist. Er ist jedoch nicht gleich dem IdentityHashCode (Mango3).
Obwohl alle String-Variablen - Mango, Mango2 und Mango3 - den gleichen Wert haben, der "Mango" ist,
identityHashCode()
ist er immer noch nicht für alle gleich.Versuchen Sie nun, diese Zeile zu kommentieren
// mango2 = "mang";
und diesmal erneut auszuführen. Sie werden sehen, dass alle dreiidentityHashCode()
unterschiedlich sind. Hmm das ist ein hilfreicher Hinweiswir wissen das wenn
hashcode(x)=N
undhashcode(y)=N
=>x is equal to y
Ich bin nicht sicher, wie Java intern funktioniert, aber ich gehe davon aus, dass dies passiert ist, als ich sagte:
Java hat eine Zeichenfolge erstellt, auf
"mango"
die die Variable somango
etwas zeigt (auf die sie verweist)Jetzt in der nächsten Zeile, als ich sagte:
Es wurde tatsächlich dieselbe Zeichenfolge wiederverwendet, die ungefähr
"mango"
so aussiehtSowohl Mango als auch Mango2 zeigen auf dieselbe Referenz. Nun, als ich sagte
Es wurde tatsächlich eine völlig neue Referenz (Zeichenfolge) für "Mango" erstellt. das sieht ungefähr so aus,
und deshalb, wenn ich die Werte für
mango == mango2
herausbringe, löschte es austrue
. und wenn ich den Wert für herausgebemango3 == mango2
, löschte er ausfalse
(selbst wenn die Werte gleich waren).und als Sie die Linie auskommentierten, wurde
// mango2 = "mang";
tatsächlich eine Zeichenfolge "mang" erstellt, die unser Diagramm wie folgt drehte:Aus diesem Grund ist der identityHashCode nicht für alle gleich.
Hoffe das hilft euch. Eigentlich wollte ich einen Testfall generieren, bei dem == fehlschlägt und gleich () besteht. Bitte zögern Sie nicht zu kommentieren und lassen Sie mich wissen, wenn ich falsch liege.
quelle
mango == mango2
dies, weil Sie keinmango2
neues String-Objekt erstellt und stattdessen nur direkt referenziert haben"mango"
?Prost :-)
quelle
Sie müssen die Funktion equals (zusammen mit anderen) überschreiben, um sie mit benutzerdefinierten Klassen zu verwenden.
Die Methode equals vergleicht die Objekte.
Der
==
binäre Operator vergleicht Speicheradressen.quelle
Sowohl == als auch .equals () beziehen sich auf dasselbe Objekt, wenn Sie .equals () nicht überschreiben.
Es ist Ihr Wunsch, was Sie tun möchten, wenn Sie .equals () überschreiben. Sie können den Status des aufrufenden Objekts mit dem Status des übergebenen Objekts vergleichen oder einfach super.equals () aufrufen.
quelle
==
ist ein Operator undequals()
ist eine Methode .Operatoren werden im Allgemeinen für primitive Typvergleiche verwendet und werden daher
==
für den Speicheradressenvergleich verwendet, und dasequals()
Verfahren wird zum Vergleichen von Objekten verwendet .quelle
quelle
Denken Sie daran, dass
.equals(...)
dies von der Klasse implementiert werden muss, die Sie vergleichen möchten. Ansonsten gibt es nicht viel Sinn; Die Version der Methode für die Object-Klasse führt dasselbe aus wie die Vergleichsoperation: Object # equals .Das einzige Mal, wenn Sie den Vergleichsoperator wirklich für Objekte verwenden möchten, ist, wen Sie Enums vergleichen. Dies liegt daran, dass jeweils nur eine Instanz eines Enum-Werts vorhanden ist. Zum Beispiel angesichts der Aufzählung
Sie werden nie mehr als eine Instanz
A
gleichzeitig haben, und das Gleiche gilt fürB
undC
. Dies bedeutet, dass Sie tatsächlich eine Methode wie folgt schreiben können:Und Sie werden überhaupt keine Probleme haben.
quelle
Wenn Sie den Code auswerten, ist es sehr klar, dass (==) gemäß der Speicheradresse verglichen wird, während equals (Object o) hashCode () der Instanzen vergleicht. Deshalb heißt es, den Vertrag zwischen equals () und hashCode () nicht zu brechen, wenn Sie später keine Überraschungen erleben.
quelle
Hier ist ein allgemeiner Regelzeile für den Unterschied zwischen
relational operator ==
undthe method .equals()
.object1 == object2
vergleicht, ob sich die Objekte, auf die von Objekt1 und Objekt2 verwiesen wird, auf denselben Speicherort in Heap beziehen .object1.equals(object2)
vergleicht die Werte von Objekt1 und Objekt2 unabhängig davon, wo sie sich im Speicher befinden .Dies kann mit String gut demonstriert werden
Szenario 1
Szenario 2
Dieser Zeichenfolgenvergleich kann als Grundlage für den Vergleich anderer Objekttypen verwendet werden.
Wenn ich beispielsweise eine Personenklasse habe , muss ich die Kriterien definieren, anhand derer ich zwei Personen vergleichen werde . Angenommen, diese Personenklasse verfügt über Instanzvariablen für Größe und Gewicht.
Erstellen Sie also Personenobjekte
person1 and person2
und vergleichen Sie diese beiden mithilfe der.equals()
I- Methode , um die Gleichheitsmethode der Personenklasse zu überschreiben und zu definieren, basierend auf welchen Instanzvariablen (Höhe oder Gewicht) der Vergleich erfolgen soll.Die
== operator will still return results based on the memory location of the two objects(person1 and person2)
.Um den Vergleich dieser Personenobjekte zu vereinfachen, habe ich die folgende Testklasse erstellt. Das Experimentieren mit diesen Konzepten wird Unmengen von Fakten enthüllen .
Ergebnis dieser Klassenausführung ist:
quelle
Beachten Sie auch, dass dies
.equals()
normalerweise==
zum Testen enthält , da dies das erste ist, auf das Sie testen möchten, wenn Sie testen möchten, ob zwei Objekte gleich sind.Und
==
tatsächlich werden Werte für primitive Typen betrachtet, für Objekte wird die Referenz überprüft.quelle
== Operator Referenz wird immer verglichen. Aber im Falle von
Es hängt von der Implementierung ab, ob die überschriebene Methode gleich ist, als das Objekt anhand der in der überschriebenen Methode angegebenen Implementierungsgrundlage zu vergleichen.
Im obigen Code enthalten sowohl das Objekt obj als auch das Objekt obj1 dieselben Daten, aber die Referenz ist nicht dieselbe, sodass gleich false und == auch zurückgegeben wird. aber wenn wir überschrieben haben gleich Methode als
Wenn Sie wissen, dass es ausgecheckt ist, werden nur für den gleichen Fall true und false zurückgegeben, die wir überschrieben haben
es vergleicht Objekt auf Basis des Inhalts (ID) des Objekts
Vergleiche immer noch Referenzen von Objekten.
quelle
Der Hauptunterschied zwischen == und equals () ist
1) == wird verwendet, um Grundelemente zu vergleichen.
Beispielsweise :
2) equals () wird verwendet, um Objekte zu vergleichen. Beispielsweise :
quelle
==
kann in vielen Objekttypen verwendet werden, aber Sie können esObject.equals
für jeden Typ verwenden, insbesondere für Strings und Google Map Markers.quelle
---- Ausgabe ----- wahr falsch wahr
quelle
Es kann sinnvoll sein, hinzuzufügen, dass für Wrapper-Objekte für primitive Typen - dh Int, Long, Double - == true zurückgegeben wird, wenn die beiden Werte gleich sind.
Wenn Sie dagegen die beiden oben genannten Longs in zwei separate ArrayLists einfügen, werden sie gleich angezeigt, == jedoch nicht.
quelle
Long a = 128l; Long b = 128l; System.out.println(a == b);
Der String-Pool (auch bekannt als Interning ) und der Integer-Pool verwischen den Unterschied weiter und können
==
in einigen Fällen anstelle von Objekten verwendet werden.equals
Dies kann zu einer höheren Leistung (?) Auf Kosten einer höheren Komplexität führen.
Z.B:
Kompromiss zwischen Komplexität: Folgendes kann Sie überraschen:
Ich rate Ihnen von solchen Mikro-Optimierung zu bleiben weg, und immer verwenden
.equals
für Objekte und==
für Primitive:quelle
Kurz gesagt lautet die Antwort "Ja".
In Java
==
vergleicht der Operator die beiden Objekte, um festzustellen, ob sie auf denselben Speicherort verweisen. Die.equals()
Methode vergleicht die beiden Objekte tatsächlich, um festzustellen, ob sie denselben Objektwert haben.quelle
Grundsätzlich wird
==
verglichen, wenn zwei Objekte dieselbe Referenz auf dem Heap haben. Wenn also nicht zwei Referenzen mit demselben Objekt verknüpft sind, ist dieser Vergleich falsch.equals()
ist eine von derObject
Klasse geerbte Methode . Diese Methode vergleicht standardmäßig, ob zwei Objekte dieselbe Referenz haben. Es bedeutet:object1.equals(object2)
<=>object1 == object2
Wenn Sie jedoch die Gleichheit zwischen zwei Objekten derselben Klasse herstellen möchten, sollten Sie diese Methode überschreiben. Es ist auch sehr wichtig, die Methode zu überschreiben,
hashCode()
wenn Sie überschrieben habenequals()
.Die Implementierung
hashCode()
beim Festlegen der Gleichheit ist Teil des Java-Objektvertrags. Wenn Sie mit Sammlungen arbeiten und diese noch nicht implementiert habenhashCode()
, können seltsame schlechte Dinge passieren:null
wird nach Ausführung des vorherigen Codes gedruckt, wenn Sie nicht implementiert habenhashCode()
.quelle
Da Java das Überladen von Operatoren nicht unterstützt, verhält sich == für jedes Objekt identisch, aber equals () ist eine Methode, die in Java überschrieben werden kann, und die Logik zum Vergleichen von Objekten kann basierend auf Geschäftsregeln geändert werden.
Der Hauptunterschied zwischen == und equals in Java besteht darin, dass "==" zum Vergleichen von Grundelementen verwendet wird, während die Methode equals () empfohlen wird, um die Gleichheit von Objekten zu überprüfen.
Der String-Vergleich ist ein gängiges Szenario für die Verwendung der Methode == und equals. Da die Überschreibung der Klasse java.lang.String gleich der Methode ist, gibt sie true zurück, wenn zwei String-Objekte denselben Inhalt enthalten, == gibt jedoch nur true zurück, wenn zwei Referenzen auf dasselbe Objekt verweisen.
Hier ist ein Beispiel für den Vergleich zweier Strings in Java auf Gleichheit mit der Methode == und equals (), um einige Zweifel auszuräumen:
quelle