Was ist der Unterschied zwischen == und equals () in Java?

622

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
Brainydexter
quelle
43
Ja, so ziemlich
John Kane
9
Ja, genau richtig. Sie können sich .equals()als sinnvoll gleichwertig
vorstellen
Mögliches Duplikat von Wie vergleiche ich Zeichenfolgen in Java?
TylerH
19
Ein Satz wie "beide Objekte zeigen auf denselben Speicherort" ist eine schlampige Sprache, was das Verständnis erschweren kann. Sie meinen: "Beide Variablen beziehen sich auf dasselbe Objekt". Beachten Sie, dass eine Variable kein Objekt ist. Eine Variable ist eine Referenz auf ein Objekt. Objekte "zeigen" auf nichts.
Jesper

Antworten:

625

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.
  • Wenn eine Klasse die Methode equals nicht überschreibt, wird standardmäßig die equals(Object o)Methode der nächsten übergeordneten Klasse verwendet, die diese Methode überschrieben hat.
  • Wenn keine übergeordneten Klassen eine Überschreibung bereitgestellt haben, wird standardmäßig die Methode aus der ultimativen übergeordneten Klasse Object verwendet, sodass Sie die 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 .
  • Denken hashCodeSie immer daran, zu überschreiben, wenn Sie überschreiben equals, um nicht "den Vertrag zu brechen". Gemäß der API muss das von der hashCode()Methode für zwei Objekte zurückgegebene Ergebnis dasselbe sein, wenn ihre equalsMethoden zeigen, dass sie gleichwertig sind. Das Gegenteil ist nicht unbedingt der Fall.
Luftkissenfahrzeug voller Aale
quelle
Wenn ==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 Verwirrungen
beseitigen
4
@JSK gibt die Werte von d1 und d2 aus und ich denke, Sie werden sehen, warum Sie false zurückgeben.
BoDidely
2
@ BoDidely Ich habe es herausgefunden. Dies lag daran, dass alle Wrapper-Klassen unveränderlich sind.
JPG
The 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/… )
Abhijeet
Unabhängig: Heute habe ich eine Meta-Frage ( meta.stackoverflow.com/questions/372795/… ) zu guten / effektiven / ... "automatischen" Nachrichten gestellt, wenn ich Fragen von Neulingen von geringer Qualität kommentiere. Das Feedback, das ich erhielt, fühlte sich ziemlich "Sie machen das völlig Falsche" an. Jetzt frage ich mich nur, wie du das siehst? Haben Sie "generische" Nachrichten in Ihrem Köcher oder schreiben Sie in solchen Fällen nur bestimmte Kommentare?
GhostCat
107

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.

Jacques Colmenero
quelle
1
Also für Strings == ist Referenz auch gleich? dh funktioniert genauso wie bei anderen Objekten?
JonnyRaa
2
(Thread Nekromantie, ich weiß ...) Für Strings, ==ist Referenz auch gleich, ja, aber es in der Regel funktioniert (wie in zwei Strings mit dem gleichen Inhalt wird in der Regel sein ==zueinander), weil, wie Java Griffe Strings. 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.
Tonio
7
Um Tonios Kommentar zu ergänzen. StringBuild aus String-Literal wird zu etwas hinzugefügt, das als " beide" bezeichnet wird String 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;"s1s2s1 == s2String constructorString s1 = new String("someString"); String s2 = new String("someString");s1 == s2
Gavin
61

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):

public final class MyEqualityTest
{
    public static void main( String args[] )
    {
        String s1 = new String( "Test" );
        String s2 = new String( "Test" );

        System.out.println( "\n1 - PRIMITIVES ");
        System.out.println( s1 == s2 ); // false
        System.out.println( s1.equals( s2 )); // true

        A a1 = new A();
        A a2 = new A();

        System.out.println( "\n2 - OBJECT TYPES / STATIC VARIABLE" );
        System.out.println( a1 == a2 ); // false
        System.out.println( a1.s == a2.s ); // true
        System.out.println( a1.s.equals( a2.s ) ); // true

        B b1 = new B();
        B b2 = new B();

        System.out.println( "\n3 - OBJECT TYPES / NON-STATIC VARIABLE" );
        System.out.println( b1 == b2 ); // false
        System.out.println( b1.getS() == b2.getS() ); // false
        System.out.println( b1.getS().equals( b2.getS() ) ); // true
    }
}

final class A
{
    // static
    public static String s;
    A()
    {
        this.s = new String( "aTest" );
    }
}

final class B
{
    private String s;
    B()
    {
        this.s = new String( "aTest" );
    }

    public String getS()
    {
        return s;
    }

}

Sie können die Erklärungen für "==" (Gleichheitsoperator) und ".equals (...)" (Methode in der Klasse java.lang.Object) über diese Links vergleichen:

Almir Campos
quelle
2
Interessantes Beispiel. Andere Perspektive als die obigen Antworten. Vielen Dank!
Andrew
1
Beste Antwort meiner Meinung nach, da es klarer ist als die anderen Volltextantworten, ohne die Erklärung zu verlieren (wenn Sie Klassen- und statische Konzepte
verstehen
44

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 equalsund 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:

String mango = "mango";
String mango2 = "mango";
System.out.println(mango != mango2);
System.out.println(mango == mango2);

wenn du sagst,

false
true

Ich werde sagen, dass Sie Recht haben, aber warum haben Sie das gesagt ? und wenn Sie sagen, die Ausgabe ist,

true
false

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:

String mango = "mango";
String mango3 = new String("mango");
System.out.println(mango != mango3);
System.out.println(mango == mango3);

Wenn Sie jetzt sagen,

false
true

Ich werde sagen, dass Sie falsch liegen, aber warum ist es jetzt falsch ? Die richtige Ausgabe für dieses Programm ist

true
false

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.)

String mango = "mango";
String mango2 = "mango";
String mango3 = new String("mango");
System.out.println(mango != mango2);
System.out.println(mango == mango2);
System.out.println(mango3 != mango2);
System.out.println(mango3 == mango2);
// mango2 = "mang";
System.out.println(mango+" "+ mango2);
System.out.println(mango != mango2);
System.out.println(mango == mango2);

System.out.println(System.identityHashCode(mango));
System.out.println(System.identityHashCode(mango2));
System.out.println(System.identityHashCode(mango3));

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 ):

false
true
true
false
mango mango
false
true
17225372
17225372
5433634

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 drei identityHashCode()unterschiedlich sind. Hmm das ist ein hilfreicher Hinweis

wir wissen das wenn hashcode(x)=Nund hashcode(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:

mango = "mango";

Java hat eine Zeichenfolge erstellt, auf "mango"die die Variable so mangoetwas zeigt (auf die sie verweist)

mango ----> "mango"

Jetzt in der nächsten Zeile, als ich sagte:

mango2 = "mango";

Es wurde tatsächlich dieselbe Zeichenfolge wiederverwendet, die ungefähr "mango"so aussieht

mango ----> "mango" <---- mango2

Sowohl Mango als auch Mango2 zeigen auf dieselbe Referenz. Nun, als ich sagte

mango3 = new String("mango")

Es wurde tatsächlich eine völlig neue Referenz (Zeichenfolge) für "Mango" erstellt. das sieht ungefähr so ​​aus,

mango -----> "mango" <------ mango2

mango3 ------> "mango"

und deshalb, wenn ich die Werte für mango == mango2herausbringe, löschte es aus true. und wenn ich den Wert für herausgebe mango3 == mango2, löschte er aus false(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:

mango ---->"mango"
mango2 ----> "mang"
mango3 -----> "mango"

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.

Govindpatel
quelle
Geschieht mango == mango2dies, weil Sie kein mango2 neues String-Objekt erstellt und stattdessen nur direkt referenziert haben "mango"?
Brt
1
Falsches Beispiel für die Verwendung von String zum Löschen von Zweifeln an == und gleich. String wird, wenn er nicht mit new verwendet wird, in den String-Pool eingefügt. Wenn dieselbe Zeichenfolge einer neuen Referenz zugewiesen wird, verweist sie auf dieselbe Zeichenfolge im Pool. Verwenden Sie daher wahrscheinlich ein benutzerdefiniertes Objektbeispiel für den Vergleich von == und .equals ().
Om252345
30

Der Operator == testet, ob zwei Variablen dieselben Referenzen haben (auch Zeiger auf eine Speicheradresse genannt) .

String foo = new String("abc");
String bar = new String("abc");

if(foo==bar)
// False (The objects are not the same)

bar = foo;

if(foo==bar)
// True (Now the objects are the same)

Während die Methode equals () prüft, ob sich zwei Variablen auf Objekte beziehen, die denselben Status (Werte) haben .

String foo = new String("abc");
String bar = new String("abc");

if(foo.equals(bar))
// True (The objects are identical but not same)

Prost :-)

Mohanraj Balasubramaniam
quelle
1
Falsch. if (foo == bar) sollte wahr sein, nicht falsch. Es wird dieselbe Zeichenfolge "adc" wiederverwendet. Testen Sie es in einer Sandbox, es wird für beide true zurückgeben.
Johnathan Logan
2
@JohnathanLogan Ich denke, es liegt am String-Interning. Jetzt habe ich zu "new String (" abc ")" gewechselt. Hoffe jetzt gibt es keine Probleme. Vielen Dank für die Information.
Mohanraj Balasubramaniam
13

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.

Andrew Carr
quelle
8

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.

Tim und Struppi
quelle
7

==ist ein Operator und equals()ist eine Methode .

Operatoren werden im Allgemeinen für primitive Typvergleiche verwendet und werden daher ==für den Speicheradressenvergleich verwendet, und das equals()Verfahren wird zum Vergleichen von Objekten verwendet .

Ayniam
quelle
6
 String w1 ="Sarat";
 String w2 ="Sarat";
 String w3 = new String("Sarat");

 System.out.println(w1.hashCode());   //3254818
 System.out.println(w2.hashCode());   //3254818
 System.out.println(w3.hashCode());   //3254818

 System.out.println(System.identityHashCode(w1)); //prints 705927765
 System.out.println(System.identityHashCode(w2)); //prints 705927765
 System.out.println(System.identityHashCode(w3)); //prints 366712642


 if(w1==w2)   //  (705927765==705927765)
 {
   System.out.println("true");
 }
 else
 {
   System.out.println("false");
 }
 //prints true

 if(w2==w3)   //  (705927765==366712642)
 {
   System.out.println("true");
 }
 else
 {
   System.out.println("false");
 }
 //prints false


 if(w2.equals(w3))   //  (Content of 705927765== Content of 366712642)
 {
   System.out.println("true");
 }
 else
 {
   System.out.println("false");
 }
 //prints true
Sarat Chandra
quelle
Einfache und beste Erklärung
Sritam Jagadev
5

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

enum FooEnum {A, B, C}

Sie werden nie mehr als eine Instanz Agleichzeitig haben, und das Gleiche gilt für Bund C. Dies bedeutet, dass Sie tatsächlich eine Methode wie folgt schreiben können:

public boolean compareFoos(FooEnum x, FooEnum y)
{
    return (x == y);
}

Und Sie werden überhaupt keine Probleme haben.

fruchtose
quelle
4

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.

    String s1 = new String("Ali");
    String s2 = new String("Veli");
    String s3 = new String("Ali");

    System.out.println(s1.hashCode());
    System.out.println(s2.hashCode());
    System.out.println(s3.hashCode());


    System.out.println("(s1==s2):" + (s1 == s2));
    System.out.println("(s1==s3):" + (s1 == s3));


    System.out.println("s1.equals(s2):" + (s1.equals(s2)));
    System.out.println("s1.equal(s3):" + (s1.equals(s3)));


    /*Output 
    96670     
    3615852
    96670
    (s1==s2):false
    (s1==s3):false
    s1.equals(s2):false
    s1.equal(s3):true
    */
Huseyin
quelle
4

Hier ist ein allgemeiner Regelzeile für den Unterschied zwischen relational operator ==und the method .equals().

object1 == object2vergleicht, 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

 public class Conditionals {

    public static void main(String[] args) {
       String str1 = "Hello";
       String str2 = new String("Hello");
       System.out.println("is str1 == str2 ? " + (str1 == str2 ));
       System.out.println("is str1.equals(str2) ? " + (str1.equals(str2 )));
    }

 }



The result is
      is str1 == str2 ? false
      is str1.equals(str2) ? true 

Szenario 2

public class Conditionals {

    public static void main(String[] args) {
       String str1 = "Hello";
       String str2 = "Hello";
       System.out.println("is str1 == str2 ? " + (str1 == str2 ));
       System.out.println("is str1.equals(str2) ? " + (str1.equals(str2 )));
    }

}

The result is 
  is str1 == str2 ? true
  is str1.equals(str2) ? true

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 person2und 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 .

package com.tadtab.CS5044;

public class Person {

private double height;
private double weight;

public double getHeight() {
    return height;
}

public void setHeight(double height) {
    this.height = height;
}

public double getWeight() {
    return weight;
}

public void setWeight(double weight) {
    this.weight = weight;
}


@Override
public int hashCode() {
    final int prime = 31;
    int result = 1;
    long temp;
    temp = Double.doubleToLongBits(height);
    result = prime * result + (int) (temp ^ (temp >>> 32));
    return result;
}

@Override
/**
 * This method uses the height as a means of comparing person objects.
 * NOTE: weight is not part of the comparison criteria
 */
public boolean equals(Object obj) {
    if (this == obj)
        return true;
    if (obj == null)
        return false;
    if (getClass() != obj.getClass())
        return false;
    Person other = (Person) obj;
    if (Double.doubleToLongBits(height) != Double.doubleToLongBits(other.height))
        return false;
    return true;
}

public static void main(String[] args) {

    Person person1 = new Person();
    person1.setHeight(5.50);
    person1.setWeight(140.00);

    Person person2 = new Person();
    person2.setHeight(5.70);
    person2.setWeight(160.00);

    Person person3 = new Person();
    person3 = person2;

    Person person4 = new Person();
    person4.setHeight(5.70);

    Person person5 = new Person();
    person5.setWeight(160.00);

    System.out.println("is person1 == person2 ? " + (person1 == person2)); // false;
    System.out.println("is person2 == person3 ? " + (person2 == person3)); // true 
    //this is because perosn3 and person to refer to the one person object in memory. They are aliases;
    System.out.println("is person2.equals(person3) ? " + (person2.equals(person3))); // true;

    System.out.println("is person2.equals(person4) ? " + (person2.equals(person4))); // true;

    // even if the person2 and person5 have the same weight, they are not equal.
    // it is because their height is different
    System.out.println("is person2.equals(person4) ? " + (person2.equals(person5))); // false;
}

}

Ergebnis dieser Klassenausführung ist:

is person1 == person2 ? false
is person2 == person3 ? true
is person2.equals(person3) ? true
is person2.equals(person4) ? true
is person2.equals(person4) ? false
Tadele Ayelegn
quelle
3

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.

bfs
quelle
3

== Operator Referenz wird immer verglichen. Aber im Falle von

equals () -Methode

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.

 class A
 {
   int id;
   String str;

     public A(int id,String str)
     {
       this.id=id;
       this.str=str;
     }

    public static void main(String arg[])
    {
      A obj=new A(101,"sam");
      A obj1=new A(101,"sam");

      obj.equals(obj1)//fasle
      obj==obj1 // fasle
    }
 }

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

 class A
 {
   int id;
   String str;

     public A(int id,String str)
     {
       this.id=id;
       this.str=str;
     }
    public boolean equals(Object obj)
    {
       A a1=(A)obj;
      return this.id==a1.id;
    }

    public static void main(String arg[])
    {
      A obj=new A(101,"sam");
      A obj1=new A(101,"sam");

      obj.equals(obj1)//true
      obj==obj1 // fasle
    }
 }

Wenn Sie wissen, dass es ausgecheckt ist, werden nur für den gleichen Fall true und false zurückgegeben, die wir überschrieben haben

entspricht Methode.

es vergleicht Objekt auf Basis des Inhalts (ID) des Objekts

aber ==

Vergleiche immer noch Referenzen von Objekten.

Sachin Jadhav
quelle
3

Der Hauptunterschied zwischen == und equals () ist

1) == wird verwendet, um Grundelemente zu vergleichen.

Beispielsweise :

        String string1 = "Ravi";
        String string2 = "Ravi";
        String string3 = new String("Ravi");
        String string4 = new String("Prakash");

        System.out.println(string1 == string2); // true because same reference in string pool
        System.out.println(string1 == string3); // false

2) equals () wird verwendet, um Objekte zu vergleichen. Beispielsweise :

        System.out.println(string1.equals(string2)); // true equals() comparison of values in the objects
        System.out.println(string1.equals(string3)); // true
        System.out.println(string1.equals(string4)); // false
Ravi Patel
quelle
2

==kann in vielen Objekttypen verwendet werden, aber Sie können es Object.equalsfür jeden Typ verwenden, insbesondere für Strings und Google Map Markers.

Liebe Wölfe
quelle
2
public class StringPool {

public static void main(String[] args) {

    String s1 = "Cat";// will create reference in string pool of heap memory
    String s2 = "Cat";
    String s3 = new String("Cat");//will create a object in heap memory

    // Using == will give us true because same reference in string pool

    if (s1 == s2) {
        System.out.println("true");
    } else {
        System.out.println("false");
    }

    // Using == with reference and Object will give us False

    if (s1 == s3) {
        System.out.println("true");
    } else {
        System.out.println("false");
    }

    // Using .equals method which refers to value

    if (s1.equals(s3)) {
        System.out.println("true");
    } else {
        System.out.println("False");
    }

    }
  }

---- Ausgabe ----- wahr falsch wahr

Aamir M Meman
quelle
2

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.

Long a = 10L;
Long b = 10L;

if (a == b) {
    System.out.println("Wrapped primitives behave like values");
}

Wenn Sie dagegen die beiden oben genannten Longs in zwei separate ArrayLists einfügen, werden sie gleich angezeigt, == jedoch nicht.

ArrayList<Long> c = new ArrayList<>();
ArrayList<Long> d = new ArrayList<>();

c.add(a);
d.add(b);
if (c == d) System.out.println("No way!");
if (c.equals(d)) System.out.println("Yes, this is true.");
Elroch
quelle
Wrapper-Objekte für primitive Typen - dh Integer, Long, Double == - geben möglicherweise nicht true zurück, selbst wenn die beiden Werte gleich sind. Es hängt nur vom Wrapper-Cache ab. Der folgende Code gibt false aus, da der Standardcache auf -128 bis 127 begrenzt ist. Long a = 128l; Long b = 128l; System.out.println(a == b);
Neetesh Bhardwaj
1

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:

assert "ab" == "a" + "b";

Integer i = 1;
Integer j = i;
assert i == j;

Kompromiss zwischen Komplexität: Folgendes kann Sie überraschen:

assert new String("a") != new String("a");

Integer i = 128;
Integer j = 128;
assert i != j;

Ich rate Ihnen von solchen Mikro-Optimierung zu bleiben weg, und immer verwenden .equalsfür Objekte und ==für Primitive:

assert (new String("a")).equals(new String("a"));

Integer i = 128;
Integer j = 128;
assert i.equals(j);
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
quelle
1

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.

JamesOstmann
quelle
0

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 der ObjectKlasse 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 haben equals().

Die Implementierung hashCode()beim Festlegen der Gleichheit ist Teil des Java-Objektvertrags. Wenn Sie mit Sammlungen arbeiten und diese noch nicht implementiert haben hashCode(), können seltsame schlechte Dinge passieren:

HashMap<Cat, String> cats = new HashMap<>();
Cat cat = new Cat("molly");
cats.put(cat, "This is a cool cat");
System.out.println(cats.get(new Cat("molly"));

nullwird nach Ausführung des vorherigen Codes gedruckt, wenn Sie nicht implementiert haben hashCode().

lmiguelvargasf
quelle
0

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:

public class TEstT{

    public static void main(String[] args) {

String text1 = new String("apple");
String text2 = new String("apple");

//since two strings are different object result should be false
boolean result = text1 == text2;
System.out.println("Comparing two strings with == operator: " + result);

//since strings contains same content , equals() should return true
result = text1.equals(text2);
System.out.println("Comparing two Strings with same content using equals method: " + result);

text2 = text1;
//since both text2 and text1d reference variable are pointing to same object
//"==" should return true
result = (text1 == text2);
System.out.println("Comparing two reference pointing to same String with == operator: " + result);

}
}
Mike Clark
quelle