781 Stimmen

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

Ich wollte klären, ob ich das richtig verstanden habe:

  • == ist ein Referenzvergleich, d.h. beide Objekte zeigen auf denselben Speicherplatz
  • .equals() wertet den Vergleich der Werte in den Objekten

746voto

Hovercraft Full Of Eels Punkte 280443

Im Allgemeinen lautet die Antwort auf Ihre Frage "Ja", aber...

  • .equals(...) vergleicht nur das, wofür es geschrieben ist, nicht mehr und nicht weniger.
  • Wenn eine Klasse die Methode equals nicht überschreibt, wird standardmäßig die Methode equals(Object o) Methode der nächstgelegenen übergeordneten Klasse, die diese Methode außer Kraft gesetzt hat.
  • Wenn keine übergeordneten Klassen eine Überschreibung bereitgestellt haben, wird standardmäßig die Methode der letzten übergeordneten Klasse, Object, verwendet, so dass die Methode Object#equals(Object o) Methode. Gemäß der Objekt-API ist dies das Gleiche wie == d.h., sie gibt true zurück wenn und nur wenn beide Variablen verweisen auf dasselbe Objekt, wenn ihre Referenzen ein und dasselbe sind. Sie testen also auf Objektgleichheit und nicht Funktionsgleichheit .
  • Denken Sie immer daran, die folgenden Funktionen außer Kraft zu setzen hashCode wenn Sie überschreiben equals um den "Vertrag nicht zu brechen". Wie in der API vorgesehen, wird das Ergebnis der hashCode() Methode für zwei Objekte debe identisch sein, wenn ihre equals Methoden zeigen, dass sie gleichwertig sind. Der Umkehrschluss lautet pas unbedingt wahr.

137voto

Jacques Colmenero Punkte 1251

In Bezug auf die Klasse String:

Die Funktion equals() Methode vergleicht den "Wert" innerhalb von 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 die beiden Objektreferenzen auf zwei verschiedene String-Instanzen verweisen, macht das keinen Unterschied. Es ist der "Wert" (d. h. der Inhalt des Zeichenarrays) innerhalb jeder String-Instanz, der verglichen wird.

Andererseits ist die "==" Betreiber vergleicht den Wert von zwei Objektreferenzen um zu sehen, ob sie sich auf dieselbe String-Instanz . Wenn der Wert beider Objektreferenzen auf dieselbe String-Instanz "verweist", wäre das Ergebnis des booleschen Ausdrucks "wahr". Wenn andererseits der Wert beider Objektreferenzen "auf" dieselbe String-Instanz verweist verschiedene String-Instanzen (obwohl beide String-Instanzen identische "Werte" haben, d. h. die Inhalte der Zeichenfelder beider String-Instanzen gleich sind), wäre das Ergebnis des booleschen Ausdrucks "false".

Wie bei jeder anderen Erklärung auch, lassen Sie es auf sich wirken.

Ich hoffe, das klärt die Sache ein wenig auf.

77voto

Almir Campos Punkte 2445

Es gibt einige kleine Unterschiede, je nachdem, ob man von "Primitiven" oder "Objekttypen" spricht; dasselbe gilt, wenn man von "statischen" oder "nicht-statischen" Mitgliedern spricht; man kann auch alle oben genannten Elemente 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:

54voto

govindpatel Punkte 2499

Der Unterschied zwischen == y equals verwirrte mich eine Zeit lang, bis ich beschloss, es mir genauer anzusehen. Viele von ihnen sagen, dass man für den Vergleich von Zeichenketten Folgendes verwenden sollte equals und nicht == . Ich hoffe, dass ich in dieser Antwort den Unterschied erklären kann.

Diese Frage lässt sich am besten beantworten, indem man sich selbst ein paar Fragen stellt, also fangen wir an:

Wie lautet die Ausgabe für das folgende Programm?

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

wenn Sie sagen,

false
true

Ich werde sagen, Sie sind rechts pero Warum haben Sie das gesagt? ? und wenn Sie sagen, die Ausgabe ist,

true
false

Ich werde sagen, Sie sind falsch Aber ich werde Sie trotzdem fragen, warum Sie das für richtig halten?

Ok, versuchen wir, diese Frage zu beantworten:

Wie lautet 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, Sie sind falsch pero warum ist es jetzt falsch ? die korrekte Ausgabe für dieses Programm ist

true
false

Bitte vergleichen Sie das obige Programm und versuchen Sie, darüber nachzudenken.

Gut. Dies könnte helfen (bitte lesen Sie dies: die Adresse des Objekts drucken - 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: Bei mir hat ideone folgendes ausgegeben ( Sie können den Code hier überprüfen ):

false
true
true
false
mango mango
false
true
17225372
17225372
5433634

Oh! Jetzt sehen Sie die identityHashCode(mango) ist gleich identityHashCode(mango2) Aber es ist nicht gleich identityHashCode(mango3)

Auch wenn alle String-Variablen - mango, mango2 und mango3 - den même Wert, der "Mango" lautet, identityHashCode() ist immer noch nicht für alle gleich.

Versuchen Sie nun, diese Zeile zu entkommentieren // mango2 = "mang"; und führen Sie es erneut aus, dann werden Sie alle drei identityHashCode() sind unterschiedlich. Hmm, das ist ein hilfreicher Hinweis

wissen wir, dass wenn hashcode(x)=N y hashcode(y)=N => x is equal to y

Ich bin mir nicht sicher, wie Java intern funktioniert, aber ich nehme an, dass dies der Fall ist, als ich sagte:

mango = "mango";

java hat eine Zeichenfolge erstellt "mango" auf die die Variable mango etwas wie dies

mango ----> "mango"

In der nächsten Zeile, als ich sagte:

mango2 = "mango";

Tatsächlich wurde dieselbe Zeichenfolge wiederverwendet "mango" die in etwa so aussieht

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

Sowohl mango als auch mango2 verweisen auf dieselbe Referenz Wenn ich nun sage

mango3 = new String("mango")

Es wurde sogar eine völlig neue Referenz (String) für "mango" erstellt, die in etwa so aussieht,

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

mango3 ------> "mango"

und deshalb habe ich, als ich die Werte für mango == mango2 hat sie true . und wenn ich den Wert für mango3 == mango2 hat sie false (auch wenn die Werte gleich waren).

und wenn Sie die Zeile unkommentiert lassen // mango2 = "mang"; Es wurde tatsächlich eine Zeichenkette "mang" erstellt, die unser Diagramm wie folgt aussehen ließ:

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

Aus diesem Grund ist der identityHashCode nicht für alle gleich.

Ich hoffe, das hilft euch. Eigentlich wollte ich einen Testfall generieren, bei dem == scheitert und equals() passieren. Bitte zögern Sie nicht, mich zu kommentieren und mir mitzuteilen, ob ich falsch liege.

35voto

Mohan Punkte 4179

Le site \== Operator prüft, ob zwei Variablen die gleiche gleiche Referenzen (auch Zeiger auf eine Speicheradresse) .

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)

Die equals() Methode prüft, ob zwei Variablen auf Objekte verweisen verweisen, die das gleicher Zustand (Werte) .

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

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

Prost :-)

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X