Die Equals -Methode in der Objektklasse wird verwendet, um festzustellen, ob ein Objekt einem anderen Objekt gleich ist. In der Objektklasse bestimmt diese Methode, ob zwei Objekte die gleiche Referenz haben. Wenn die beiden Objekte die gleiche Referenz haben, müssen sie gleich sein. Aus dieser Sicht ist es vernünftig, es als Standardoperation zu verwenden. Für die meisten Klassen ist dieses Urteil jedoch bedeutungslos. Zum Beispiel ist es völlig bedeutungslos zu vergleichen, ob zwei Printstreams auf diese Weise gleich sind. Es ist jedoch häufig notwendig, die Gleichheit der Zustände von zwei Objekten zu erkennen. Wenn die Zustände der beiden Objekte gleich sind, gelten die beiden Objekte als gleich. Im Allgemeinen müssen gleiche Vergleiche in benutzerdefinierten Klassen umschreiben.
Hier sind einige Vorschläge zum Schreiben einer perfekten Equals () -Methode:
(1) Der explizite Parameter heißt OtherObject und muss in eine Variable konvertiert werden
(2) Erkennen Sie, ob dieses und ein anderesObject auf dasselbe Objekt beziehen:
if (this == otherObject) return true;
Diese Aussage ist nur eine Optimierung. Tatsächlich ist dies eine Form, die oft übernommen wird. Denn die Berechnung dieser Gleichung ist viel günstiger als der Vergleich der Felder in einer Klasse der Klasse nacheinander.
(3) Überprüfen Sie, ob ein anderesObject null ist und ob NULL, FALSE zurück. Dieser Test ist notwendig.
if (otherObject == null) return false;
(4) Vergleichen Sie, ob dieses und ein anderesObject zur gleichen Klasse gehört. Wenn sich die Semantik der Gleichen in jeder Unterklasse ändert, verwenden Sie GetClass (), um sie zu erkennen, was sich selbst als Zielklasse nimmt
if (getClass ()! = otherObject.getClass ()) return false;
Wenn alle Unterklassen die gleiche Semantik haben, verwenden Sie die Instanzkennung
if (! (AndereObject Instance von ClassName)) return false;
(5) Konvertieren Sie ein anderesObject in eine Variable des entsprechenden Typs:
ClassName other = (className) otherObject;
(6) Vergleiche nun alle Domänen, die verglichen werden müssen. Verwenden Sie ==, um die Basistypdomäne zu vergleichen und gleich zu vergleichen, um die Objektdomäne zu vergleichen. Rückgabe true, wenn alle Felder übereinstimmen, andernfalls geben Sie false zurück;
return field1 == other.field1 && field2.equals (other.field2)
Wenn Equals in einer Unterklasse neu definiert wird, müssen Sie die Call Super.equals (Other) einbeziehen. Wenn die Erkennung fehlschlägt, ist es unmöglich, gleich zu sein. Wenn die Domänen in der Superklasse gleich sind, vergleichen Sie die Instanzdomänen in der Unterklasse.
Für Felder vom Array-Typ können Sie die statische Arrays verwenden. Ausgleiche, um festzustellen, ob die entsprechenden Elemente gleich sind.
Schauen wir uns einige Vergleichsbeispiele für Saiten an:
Zeichenfolge a = "ABC"; Zeichenfolge b = "ABC"; String c = neuer String ("ABC"); Zeichenfolge d = neuer String ("ABC"); System.out.println (a == b); // true, weil String -Konstanten in Java geteilt werden, gibt es nur ein Kopiersystem.out.println (a == c); // False A und C gehören 2 verschiedenen Objekten System.out.println (A.Equals (c)); // true Da die Equals -Methode des String -Objekts die Werte im Objekt vergleicht, gibt es true zurück. (Anders als die Equals -Methode des Objekts) system.out.println (c == d); // false Obwohl die Werte in den Objekten gleich sind, gehören sie zu 2 verschiedenen Objekten, sodass sie kein gleiches System sind. // WAHREinfach ausgedrückt, wenn Stringkonstanten verglichen werden, ist es das gleiche wie das von Gleichen zurückgegebene Ergebnis. Wenn Sie den Wert des String -Objekts vergleichen möchten, verwenden Sie gleich.
Siehe ein Beispiel für die Verwendung von Gleichen:
Paket Kapitel05.Equalstest; import Java.util.*; public class Equalstest {public static void main (String [] args) {Mitarbeiter Alice1 = neuer Mitarbeiter ("Alice Adams", 75000, 1987, 12, 15); Mitarbeiter Alice2 = Alice1; // Referenz auf denselben Objekt -Mitarbeiter alice3 = neuer Mitarbeiter ("Alice Adams", 75000, 1987, 12, 15); Mitarbeiter Bob = neuer Mitarbeiter ("Bob Brandson", 50000, 1989, 10, 1); System.out.println ("alice1 == alice2:" + (alice1 == alice2)); System.out.println ("alice1 == alice3:" + (alice1 == alice3)); System.out.println ("alice1.equals (alice3):" + (alice1.equals (alice3)); System.out.println ("alice1.equals (bob):" + (alice1.equals (bob))); System.out.println (Bob.ToString ()); }} Klasse Mitarbeiter {public Employee (String N, Double S, Int Year, int Month, int Day) {name = n; Gehalt = S; Gregoriancalendar -Kalender = neuer Gregoriancalendar (Jahr, Monat, Tag); hireday = calendar.getTime (); } public String getName () {return name; } public double getSalary () {Rückgabegehalt; } public date gethireday () {return hireday; } public void raiseSalary (Double Bypercent) {Double Raise = Gehalt * BY -Percent / 100; Gehalt += Erhöhung; } @Override public boolean Equals (Object OtherObject) {// Ein kurzer Test, um festzustellen, ob die Objekte identifiziert werden, wenn (this == OtherObject) true; // muss falsch zurückgeben, wenn der explizite Parameter null ist, wenn (otherObject == null) false zurückgeben; // Wenn die Klassik nicht übereinstimmen, können sie nicht gleich sein, wenn (getClass ()! = otherObject.getClass ()) false zurückgeben; // Jetzt wissen wir, dass ein anderesObject ein nicht null-Mitarbeiter ist. // Testen Sie, ob die Felder die Werte identifiziert haben, name.equals (other.name) && salary == Andere.Salary && hireday.equals (other.Hireday); } @Override public int HashCode () {return 7 * name.hashCode () + 11 * neues double (Gehalt) .hashCode () + 13 * hireday.hashCode (); } @Override public String toString () {return getClass (). GetName () + "[name =" + name + ", salary =" + halt + ", hireday =" + hireday + "]"; } privater Zeichenfolge Name; privates Doppelgehalt; privates Datum Hireday; } Class Manager erweitert den Mitarbeiter {public Manager (String N, Double S, int Jahr, int Monat, int Tag) {Super (n, s, Jahr, Monat, Tag); bouns = 0; } @Override public double getSalary () {Double Basesalary = Super.getSalary (); Rückgabe bassalary + bouns; } public void setBouns (double b) {bouns = b; } @Override public boolean Equals (Object OtherObject) {if (! Super.equals (otherObject)) return false; Manager Andere = (Manager) OtherObject; // super gleichen überprüft, dass dies und andere derselben Klasse return bouns == other.bouns; } @Override public int HashCode () {return Super.hashCode () + 17 * neues double (bouns) .hashCode (); } @Override public String toString () {return Super.toString () + "[bouns =" + bouns + "]"; } private doppelte Bouns; } Gehen Sie tiefer und unterteilen Sie es in 2 Kategorien gemäß "ob die Klasse die Equals () -Methode überschreibt".
(1) Wenn eine Klasse die Methode Equals () nicht überschreibt, wenn sie die beiden Objekte über Equals () vergleicht, wird tatsächlich verglichen, ob die beiden Objekte das gleiche Objekt sind. Zu diesem Zeitpunkt entspricht es dem Vergleich dieser beiden Objekte mit "==".
(2) Wir können die Equals () -Methode der Klasse überschreiben lassen, um gleich () zu vergleichen, ob zwei Objekte auf andere Weise gleich sind. Die übliche Praxis lautet: Wenn der Inhalt zweier Objekte gleich ist, gibt die Equals () -Methode wahr; Ansonsten kehrt es Fasle zurück.
Lassen Sie uns als nächstes ein Beispiel geben, um die oben genannten zwei Situationen zu erklären.
1. Der Fall von "nicht überschreibende Equals () -Methode"
Der Code ist wie folgt (Equalstest1.java):
Java.util importieren. */public class EqualStest1 {public static void main (String [] args) {// 2 neue Person -Objekte mit demselben Inhalt erstellen, // Verwenden Sie gleich, ob sie gleicher Person sind p1 = neue Person ("eee", 100); Person p2 = neue Person ("eee", 100); System.out.printf ("%s/n", p1.equals (p2)); } /*** @Desc Person Class. */ private statische Klasse Person {int age; Zeichenfolge Name; public person (String name, int age) {this.name = name; this.age = Alter; } public String toString () {return name + " -" + älter; }}} Auslaufergebnisse:
Kopieren Sie den Code wie folgt: Falsch
Ergebnisse Analyse Wir verwenden P1.equals (P2), um zu vergleichen, ob p1 und p2 gleich sind. Tatsächlich wird die Equals () -Methode von Object.java aufgerufen, dh die (p1 == p2) genannte. Es ist zu vergleichen, ob "p1 und p2 das gleiche Objekt sind".
Aus den Definitionen von P1 und P2 können wir sehen, dass ihr Inhalt zwar gleich ist, aber zwei verschiedene Objekte sind! Daher ist das Rückgabeergebnis falsch.
2. Die Situation des "Überschreibens gleich () () Methode"
Wir modifizieren die oben gleichen Stest1.java: Überschreiben Sie die Equals () -Methode.
Der Code ist wie folgt (Equalstest2.java):
Java.util importieren. */public class EqualStest2 {public static void main (String [] args) {// 2 neue Person -Objekte mit demselben Inhalt erstellen, // Verwenden Sie gleich, ob sie gleicher Person sind p1 = neue Person ("eee", 100); Person p2 = neue Person ("eee", 100); System.out.printf ("%s/n", p1.equals (p2)); } /*** @Desc Person Class. */ private statische Klasse Person {int age; Zeichenfolge Name; public person (String name, int age) {this.name = name; this.age = Alter; } public String toString () {return name + " -" + älter; } / *** @Desc Override Equals Methode* / @Override public boolean Equals (Objekt obj) {if (obj == null) {return false; } // Wenn es dasselbe Objekt ist, geben Sie true zurück, andernfalls geben Sie false zurück, wenn (this == obj) {return true; } // Beurteilen Sie, ob der Typ gleich ist, wenn (this.getClass ()! = Obj.getClass ()) {return false; } Person Person = (Person) obj; return name.equals (person.name) && age == Person.age; }}} Auslaufergebnisse:
Kopieren Sie den Code wie folgt: Richtig
Ergebnisanalyse:
Wir haben die Equals () -Funktion der Person in EqualStest2.java überschreiben: Wenn der Name und das Alter der beiden Personen -Objekte gleich sind, gibt es wahr zurück.
Daher gibt das Run -Ergebnis wahr zurück.
Lassen Sie uns jedoch über die Anforderungen von Java für Equals () sprechen. Es gibt die folgenden Punkte:
Symmetrie: Wenn X.equals (y) "wahr" zurückgibt, sollten Y.Equals (x) auch "True" zurückgeben.
Reflexionsvermögen: X.Equals (x) muss "wahr" zurückgeben.
Analogie: Wenn X.Equals (y) "true" zurückgibt und Y.Equals (z) "true" zurückgibt, sollten Z.Equals (x) auch "true" zurückgeben.
Konsistenz: Wenn X.equals (y) "wahr" zurückgibt, solange der Inhalt von x und y unverändert bleibt, egal wie oft Sie X.Equals (y) wiederholen, wird die Rendite "wahr" sein.
Nicht-leer, x.equals (null), gibt immer "falsch" zurück; X.Equals (Objekte verschiedener Typen und x) gibt immer "Falsch" zurück.
Lassen Sie uns nun die Rolle von Equals () überprüfen: Bestimmen Sie, ob zwei Objekte gleich sind. Wenn wir Equals () neu schreiben, ist es unmöglich, seine Funktion zu ändern!
Was ist der Unterschied zwischen Equals () und ==?
==: Seine Funktion besteht darin, festzustellen, ob die Adressen von zwei Objekten gleich sind. Das heißt, bestimmen Sie, ob die beiden Objekte das gleiche Objekt sind.
Equals (): Seine Funktion ist festzustellen, ob zwei Objekte gleich sind. Es hat jedoch im Allgemeinen zwei Nutzungsbedingungen (es wurde im vorherigen Teil 1 ausführlich beschrieben):
In Fall 1 überschreibt die Klasse die Equals () -Methode nicht. Wenn dann zwei Objekte dieser Klasse über Equals () verglichen werden, ist es dem Vergleich dieser beiden Objekte mit "==" gleichwertig.
In Fall 2 überschreibt die Klasse die Equals () -Methode. Im Allgemeinen überschreiben wir die Equals () -Methode, um den Inhalt von zwei Objekten gleich zu gestalten. Wenn ihre Inhalte gleich sind, gibt es wahr zurück (dh die beiden Objekte werden als gleich angesehen).
Vergleichen Sie im Folgenden ihre Unterschiede anhand von Beispielen.
Der Code ist wie folgt:
Java.util importieren. */public class EqualStest3 {public static void main (String [] args) {// 2 neue Person -Objekte mit demselben Inhalt erstellen, // Verwenden Sie gleich, ob sie gleicher Person sind p1 = neue Person ("eee", 100); Person p2 = neue Person ("eee", 100); System.out.printf ("p1.equals (p2): %s/n", p1.equals (p2)); System.out.printf ("p1 == p2: %s/n", p1 == p2); } /*** @Desc Person Class. */ private statische Klasse Person {int age; Zeichenfolge Name; public person (String name, int age) {this.name = name; this.age = Alter; } public String toString () {return name + " -" + älter; } / *** @Desc Override Equals Methode* / @Override public boolean Equals (Objekt obj) {if (obj == null) {return false; } // Wenn es dasselbe Objekt ist, geben Sie true zurück, andernfalls geben Sie false zurück, wenn (this == obj) {return true; } // Beurteilen Sie, ob der Typ gleich ist, wenn (this.getClass ()! = Obj.getClass ()) {return false; } Person Person = (Person) obj; return name.equals (person.name) && age == Person.age; }}} Auslaufergebnisse:
p1.equals (p2): Truep1 == P2: Falsch
Ergebnisanalyse:
In gleichen stest3.java:
(1) p1.equals (p2)
Dies soll bestimmen, ob der Inhalt von P1 und P2 gleich ist. Da Person die Equals () -Methode überschreibt und dies gleich () verwendet wird, um festzustellen, ob der Inhalt von p1 und p2 gleich ist, sind genau der Inhalt von p1 und p2 gleich; Daher kehren Sie wahr zurück.
(2) p1 == p2
Dies soll bestimmen, ob P1 und P2 das gleiche Objekt sind. Da es sich jeweils um zwei neue Personenobjekte handelt; Daher fälschlich zurückkehren.