Heim Java javaLernprogramm Überschreiben der Methode equal()

Überschreiben der Methode equal()

Dec 16, 2016 am 10:38 AM
equals

1. Warum muss die Methode equal() neu geschrieben werden?

Bestimmen Sie, ob zwei Objekte logisch gleich sind, indem Sie beispielsweise anhand der Mitgliedsvariablen der Klasse beurteilen, ob Instanzen zweier Klassen gleich sind. Die Methode „equals“ im geerbten Objekt kann jedoch nur bestimmen, ob zwei Referenzvariablen gleich sind dasselbe. Auf diese Weise müssen wir häufig die Methode equal() überschreiben.

Wenn wir Elemente zu einer Sammlung ohne doppelte Objekte hinzufügen, speichert die Sammlung häufig Objekte. Wir müssen zunächst feststellen, ob es bekannte Objekte in der Sammlung gibt, daher müssen wir die Methode „equals“ überschreiben.

2. Wie überschreibe ich die Methode equal()?

Anforderungen zum Überschreiben der Methode „equals“:
1. Reflexivität: x.equals(x) sollte für jede Nicht-Null-Referenz x „true“ zurückgeben.
2. Symmetrie: Wenn x.equals(y) für jede Referenz auf x und y true zurückgibt, sollte y.equals(x) auch true zurückgeben.
3. Transitivität: Wenn für jede Referenz x, y und z x.equals(y) true und y.equals(z) true zurückgibt, sollte x.equals(z) auch true zurückgeben.
4. Konsistenz: Wenn sich die durch x und y referenzierten Objekte nicht geändert haben, sollte der wiederholte Aufruf von x.equals(y) das gleiche Ergebnis zurückgeben.
5. Nicht-Nullbarkeit: Für jede Nicht-Null-Referenz x sollte x.equals(null) false zurückgeben.

Format:


Java-Code

public boolean equals(Object obj) {  
    if(this == obj)  
        return false;  
    if(obj == null)  
        return false;  
    if(getClass() != obj.getClass() )  
        return false;  
    MyClass other = (MyClass)obj;  
    if(str1 == null) {  
         if(obj.str1 != null) {  
              return false;  
         }  
    }else if (!str1.equals(other.str1) )  
             return false;  
     }  
    if(var1 != other.var1)  
        return false;  
    return true;  
}
Nach dem Login kopieren

Wenn der Unterklasse neue Funktionen hinzugefügt werden und dabei die Methode „equals“ beibehalten wird, dann ist dies der Fall komplizierter.


Als nächstes wollen wir die obige Konvention anhand von Beispielen verstehen. Wir beginnen mit einer einfachen, nicht veränderlichen 2D-Punktklasse:

public class Point{ 
  private final int x; 
  private final int y; 
  public Point(int x, int y){ 
    this.x = x; 
    this.y = y; 
  } 
  public boolean equals(Object o){ 
    if(!(o instanceof Point)) 
      return false; 
    Point p = (Point)o; 
      return p.x == x && p.y == y; 
  } 
}
Nach dem Login kopieren


Angenommen, Sie möchten diese Klasse erweitern, um einem Punkt Farbinformationen hinzuzufügen:

public class ColorPoint extends Point{ 
  private Color color; 
  public ColorPoint(int x, int y, Color color){ 
    super(x, y); 
    this.color = color; 
  } 
  //override equasl() 
  public boolean equals(Object o){ 
    if(!(o instanceof ColorPoint)) 
     return false; 
    ColorPoint cp = (ColorPoint)o; 
    return super.equals(o) && cp.color==color; 
  } 
}
Nach dem Login kopieren


Wir überschreiben die Methode „equals“, sodass sie nur dann „true“ zurückgibt, wenn der tatsächliche Parameter ein anderer farbiger Punkt mit derselben Position und Farbe ist. Das Problem bei dieser Methode besteht jedoch darin, dass Sie beim Vergleich eines normalen Punkts mit einem farbigen Punkt und umgekehrt möglicherweise unterschiedliche Ergebnisse erhalten:

public static void main(String[] args){ 
  Point p = new Point(1, 2); 
  ColorPoint cp = new ColorPoint(1, 2, Color.RED); 
  System.out.println(p.equals(cp)); 
  System.out.println(cp.eqauls(p)); 
}
Nach dem Login kopieren

Laufergebnisse:
wahr
false
Ein solches Ergebnis verstößt offensichtlich gegen die Symmetrie. Sie können Folgendes versuchen, um dieses Problem zu beheben: Lassen Sie ColorPoint.equals Farbinformationen ignorieren, wenn Sie „gemischte Vergleiche“ durchführen:

public boolean equals(Object o){ 
  if(!(o instanceof Point)) 
    return false; 
  //如果o是一个普通点,就忽略颜色信息 
  if(!(o instanceof ColorPoint)) 
    return o.equals(this); 
  //如果o是一个有色点,就做完整的比较 
  ColorPoint cp = (ColorPoint)o; 
  return super.equals(o) && cp.color==color; 
}
Nach dem Login kopieren

Was wird sein das Ergebnis dieser Methode? Testen wir es zuerst:

public static void main(String[] args){ 
  ColorPoint p1 = new ColorPoint(1, 2, Color.RED); 
  Point p2 = new Point(1, 2); 
  ColorPoint p3 = new ColorPoint(1, 2, Color.BLUE); 
  System.out.println(p1.equals(p2)); 
  System.out.println(p2.equals(p1)); 
  System.out.println(p2.equals(p3)); 
  System.out.println(p1.eqauls(p3)); 
}
Nach dem Login kopieren

Laufendes Ergebnis:
wahr
wahr
wahr
falsch

Diese Methode bietet zwar Symmetrie, aber bei der Aufwand der Transitivität (konventionell geben sowohl p1.equals(p2) als auch p2.eqauals(p3) true zurück, und p1.equals(p3) sollte auch true zurückgeben). Wie kann man es lösen?

Tatsächlich ist dies eine grundlegende Frage zu Äquivalenzbeziehungen in objektorientierten Sprachen. Es gibt keine einfache Möglichkeit, eine instanziierbare Klasse zu erweitern, um neue Funktionen hinzuzufügen und dabei die Gleichheitskonvention beizubehalten. Die neue Lösung besteht darin, ColorPoint nicht mehr Point erweitern zu lassen, sondern ein privates Point-Feld und eine öffentliche Ansichtsmethode zu ColorPoint hinzuzufügen:

public class ColorPoint{ 
  private Point point; 
  private Color color; 
  public ColorPoint(int x, int y, Color color){ 
    point = new Point(x, y); 
    this.color = color; 
  } 
  //返回一个与该有色点在同一位置上的普通Point对象 
  public Point asPoint(){ 
    return point; 
  } 
  public boolean equals(Object o){ 
    if(o == this) 
     return true; 
    if(!(o instanceof ColorPoint)) 
     return false; 
    ColorPoint cp = (ColorPoint)o; 
    return cp.point.equals(point)&& 
             cp.color.equals(color); 
  } 
}
Nach dem Login kopieren

Es gibt noch eine andere Die Lösung besteht darin, Point als zu entwerfen eine abstrakte Klasse, sodass Sie Unterklassen der abstrakten Klasse neue Funktionen hinzufügen können, ohne den Equals-Vertrag zu verletzen. Da abstrakte Klassen keine Instanzen der Klasse erstellen können, treten keine der oben genannten Probleme auf.

Wichtige Punkte beim Überschreiben der Methode „equals“:
1. Verwenden Sie den ==-Operator, um zu prüfen, „ob der tatsächliche Parameter eine Referenz auf das Objekt ist“.

2. Bestimmen Sie, ob der tatsächliche Parameter null ist
3. Verwenden Sie den Operator „instanceof“, um zu prüfen, „ob der tatsächliche Parameter vom richtigen Typ ist“.
4. Konvertieren Sie die tatsächlichen Parameter in den richtigen Typ.
5. Überprüfen Sie für jedes „Schlüssel“-Feld in dieser Klasse, ob das Feld im tatsächlichen Parameter mit dem entsprechenden Feldwert im aktuellen Objekt übereinstimmt
. Für Felder mit Basistypen, die weder Float noch Double sind, können Sie zum Vergleich den ==-Operator
verwenden. Für Felder mit Objektreferenztypen können Sie die Methode equal des referenzierten Objekts
rekursiv aufrufen Felder, verwenden Sie zuerst Float.floatToIntBits, um in Werte vom Typ „int“ zu konvertieren,
Verwenden Sie dann den Operator ==, um Werte vom Typ „int“ zu vergleichen Verwenden Sie dann den ==-Operator, um den Wert des Typs
long zu vergleichen.
6. Nachdem Sie die Gleichheitsmethode geschrieben haben, sollten Sie sich drei Fragen stellen: Ist sie symmetrisch, transitiv und konsistent? (Die beiden anderen Merkmale werden normalerweise von selbst erfüllt.) Wenn die Antwort „Nein“ lautet, ermitteln Sie bitte den Grund, warum diese Merkmale nicht erfüllt sind, und ändern Sie dann den Code der Methode „equals“.



Weitere Artikel zum Umschreiben der Methode equal() finden Sie auf der chinesischen PHP-Website!

Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn

Heiße KI -Werkzeuge

Undresser.AI Undress

Undresser.AI Undress

KI-gestützte App zum Erstellen realistischer Aktfotos

AI Clothes Remover

AI Clothes Remover

Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

Undress AI Tool

Undress AI Tool

Ausziehbilder kostenlos

Clothoff.io

Clothoff.io

KI-Kleiderentferner

AI Hentai Generator

AI Hentai Generator

Erstellen Sie kostenlos Ai Hentai.

Heißer Artikel

R.E.P.O. Energiekristalle erklärten und was sie tun (gelber Kristall)
3 Wochen vor By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Beste grafische Einstellungen
3 Wochen vor By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. So reparieren Sie Audio, wenn Sie niemanden hören können
3 Wochen vor By 尊渡假赌尊渡假赌尊渡假赌

Heiße Werkzeuge

Notepad++7.3.1

Notepad++7.3.1

Einfach zu bedienender und kostenloser Code-Editor

SublimeText3 chinesische Version

SublimeText3 chinesische Version

Chinesische Version, sehr einfach zu bedienen

Senden Sie Studio 13.0.1

Senden Sie Studio 13.0.1

Leistungsstarke integrierte PHP-Entwicklungsumgebung

Dreamweaver CS6

Dreamweaver CS6

Visuelle Webentwicklungstools

SublimeText3 Mac-Version

SublimeText3 Mac-Version

Codebearbeitungssoftware auf Gottesniveau (SublimeText3)

Wie implementiere ich mehrstufige Caching in Java-Anwendungen mit Bibliotheken wie Koffein oder Guava-Cache? Wie implementiere ich mehrstufige Caching in Java-Anwendungen mit Bibliotheken wie Koffein oder Guava-Cache? Mar 17, 2025 pm 05:44 PM

In dem Artikel wird in der Implementierung von mehrstufigem Caching in Java mithilfe von Koffein- und Guava-Cache zur Verbesserung der Anwendungsleistung erläutert. Es deckt die Einrichtungs-, Integrations- und Leistungsvorteile sowie die Bestrafung des Konfigurations- und Räumungsrichtlinienmanagements ab

Wie kann ich funktionale Programmierungstechniken in Java implementieren? Wie kann ich funktionale Programmierungstechniken in Java implementieren? Mar 11, 2025 pm 05:51 PM

In diesem Artikel wird die Integration der funktionalen Programmierung in Java unter Verwendung von Lambda -Ausdrücken, Streams -API, Methodenreferenzen und optional untersucht. Es zeigt Vorteile wie eine verbesserte Lesbarkeit der Code und die Wartbarkeit durch SUKTIVE UND VERUSNAHMETALITÄT

Wie funktioniert der Klassenladungsmechanismus von Java, einschließlich verschiedener Klassenloader und deren Delegationsmodelle? Wie funktioniert der Klassenladungsmechanismus von Java, einschließlich verschiedener Klassenloader und deren Delegationsmodelle? Mar 17, 2025 pm 05:35 PM

Mit der Klassenbelastung von Java wird das Laden, Verknüpfen und Initialisieren von Klassen mithilfe eines hierarchischen Systems mit Bootstrap-, Erweiterungs- und Anwendungsklassenloadern umfasst. Das übergeordnete Delegationsmodell stellt sicher

Wie kann ich JPA (Java Persistence-API) für Objektrelationszuordnungen mit erweiterten Funktionen wie Caching und faulen Laden verwenden? Wie kann ich JPA (Java Persistence-API) für Objektrelationszuordnungen mit erweiterten Funktionen wie Caching und faulen Laden verwenden? Mar 17, 2025 pm 05:43 PM

In dem Artikel werden mit JPA für Objektrelationszuordnungen mit erweiterten Funktionen wie Caching und faulen Laden erläutert. Es deckt Setup, Entity -Mapping und Best Practices zur Optimierung der Leistung ab und hebt potenzielle Fallstricke hervor. [159 Charaktere]

Wie benutze ich Maven oder Gradle für das fortschrittliche Java -Projektmanagement, die Erstellung von Automatisierung und Abhängigkeitslösung? Wie benutze ich Maven oder Gradle für das fortschrittliche Java -Projektmanagement, die Erstellung von Automatisierung und Abhängigkeitslösung? Mar 17, 2025 pm 05:46 PM

In dem Artikel werden Maven und Gradle für Java -Projektmanagement, Aufbau von Automatisierung und Abhängigkeitslösung erörtert, die ihre Ansätze und Optimierungsstrategien vergleichen.

Wie verwende ich Javas NIO-API (neue Eingang/Ausgabe) für nicht blockierende I/O? Wie verwende ich Javas NIO-API (neue Eingang/Ausgabe) für nicht blockierende I/O? Mar 11, 2025 pm 05:51 PM

In diesem Artikel werden die NIO-API von Java für nicht blockierende E/A erläutert, wobei Selektoren und Kanäle verwendet werden, um mehrere Verbindungen effizient mit einem einzelnen Thread zu verarbeiten. Es beschreibt den Prozess, die Vorteile (Skalierbarkeit, Leistung) und mögliche Fallstricke (Komplexität,

Wie erstelle und verwende ich benutzerdefinierte Java -Bibliotheken (JAR -Dateien) mit ordnungsgemäßem Versioning und Abhängigkeitsmanagement? Wie erstelle und verwende ich benutzerdefinierte Java -Bibliotheken (JAR -Dateien) mit ordnungsgemäßem Versioning und Abhängigkeitsmanagement? Mar 17, 2025 pm 05:45 PM

In dem Artikel werden benutzerdefinierte Java -Bibliotheken (JAR -Dateien) mit ordnungsgemäßem Versioning- und Abhängigkeitsmanagement erstellt und verwendet, wobei Tools wie Maven und Gradle verwendet werden.

Wie verwende ich Javas Sockets -API für die Netzwerkkommunikation? Wie verwende ich Javas Sockets -API für die Netzwerkkommunikation? Mar 11, 2025 pm 05:53 PM

In diesem Artikel wird die Socket-API von Java für die Netzwerkkommunikation beschrieben, die das Setup des Client-Servers, die Datenbearbeitung und entscheidende Überlegungen wie Ressourcenverwaltung, Fehlerbehandlung und Sicherheit abdeckt. Es untersucht auch die Leistungsoptimierungstechniken, ich

See all articles