Heim  >  Artikel  >  Java  >  Ein Überblick über die tiefergehenden Methoden zum Überschreiben von Equals in Java

Ein Überblick über die tiefergehenden Methoden zum Überschreiben von Equals in Java

Y2J
Y2JOriginal
2017-04-24 16:07:411271Durchsuche

Ich habe kürzlich mit meinen Kollegen über den Unterschied zwischen gleich und == gesprochen. Dies ist eigentlich eine sehr alte und einfache Frage, aber wenn Sie die Equals-Methode selbst überschreiben möchten, stellen Sie fest, dass Sie einige Dinge nicht wissen, die Sie aber wissen müssen. Das Abdecken von Gleichberechtigung erfordert viel Aufmerksamkeit. Obwohl Object eine sehr spezifische Klasse ist, besteht ihre Hauptaufgabe darin, sie zu erweitern. Alle seine nicht endgültigen Methoden haben klare universelle Konventionen. Weil sie als überschriebene Methoden konzipiert sind. Jede Klasse, die equal, hashCode, toString, clone und finalize überschreibt, ist für die Einhaltung der allgemeinen Konventionen dieser Methoden verantwortlich. Wenn dies nicht möglich ist, wird es schwierig sein, den gewünschten Effekt zu erzielen, wenn mehrere Klassen kombiniert werden.

Überschreiben Sie nicht die Methode „equals“


Das Überschreiben der Methode „equals“ scheint einfach zu sein, aber es gibt viele überschreibende Methoden, die Fehler verursachen können. Der einfachste Weg, diesen Fehler zu vermeiden, besteht darin, „equals“ nicht zu überschreiben. In diesem Fall ist jede Klasseninstanz nur sich selbst gleich. Unter welchen Umständen können wir uns also dafür entscheiden, die Methode „equals“ nicht zu überschreiben?

Jede Instanz einer Klasse ist von Natur aus einzigartig

Dies gilt für Klassen, die aktive Entitäten und nicht Werte darstellen, wie beispielsweise jede Thread-Instanz. Es ist für uns sinnlos, es mit der Methode „equals“ zu vergleichen, da jeder Thread einzigartig ist. In diesem Fall müssen wir die Methode „equals“ nicht überschreiben, da „equals“ in der Klasse „Object“ völlig ausreicht.

Implementierung der Methode „equals“ in der Object-Klasse:

 public boolean equals(Object obj) { return (this == obj);  }

Ist egal, ob die Klasse eine logische Gleichheitsbeurteilung erfordert

Einige Klassen sind „numerische Klassen“. Der Vergleich von Größen und mathematischen Operationen ist die Aufgabe dieser Klassen. In diesem Fall müssen wir die in der Klasse gespeicherten Werte vergleichen und ein logisches Gleichheitsurteil fällen. Abgesehen davon gibt es in den meisten Klassen nicht das Konzept „ob das eine dem anderen gleich ist“. Solche Klassen, denen die logische Gleichheit egal ist, müssen die Methode equals nicht überschreiben.

Das von der Superklasse implementierte Gleichheitsverfahren ist auf Unterklassen anwendbar.

Zum Beispiel gibt es keinen Unterschied in der Gleichheitsmethode der HashSet-Klasse, die die AbstractSet-Klasse erbt. Dann verwenden Sie direkt HashSet. Verwenden Sie einfach die Gleichheitsmethode von AbstractSet.

Überschreiben Sie die Methode „equals“

Im Gegensatz zu oben müssen wir die Methode „equals“ überschreiben: Wenn die Klasse ihr eigenes Konzept der logischen Gleichheit hat, und der übergeordneten Klasse Es ist keine Überschreibung der Methode „equals“ verfügbar. Zu diesem Zeitpunkt müssen wir es selbst abdecken.

Die Äquivalenzbeziehung der Methode „equals“ in der Sammlung


Die Methode „equals“ implementiert die Äquivalenzbeziehung. Ich habe das Konzept der Äquivalenzbeziehungen in der diskreten Mathematik gelernt. Wenn eine binäre Beziehung auf R die spontane Symmetrie und Transitivität erfüllt, ist sie äquivalent. Lassen Sie uns die Beziehung zwischen Gleichheit und diesen drei Eigenschaften im Detail analysieren.

Reflexivität: Für jeden Nicht-Null-Referenzwert x muss x.equals(x) true zurückgeben

Symmetrie: Für Für jeden nicht -Null-Referenzwerte x und y, genau dann, wenn y.equals(x) true zurückgibt, muss x.equals(y) true zurückgeben

Transitivität: Für alle Für nicht -null Referenzwerte x, y und z, wenn x.equals(y) true zurückgibt und y.equals(z) auch true zurückgibt, dann muss x.equals(z) true zurückgeben.

Reflexivität: ∀ a ∈A, => (a, a) ∈ R
Symmetrie: (a, b) ∈R∧ a ≠ b => 🎜> Transitivität: (a, b)∈R, (b, c)∈R => (a, c)∈R

Der Vergleich dieser drei Eigenschaften ist kein Problem. Es ist ersichtlich, dass die Gleichheitsmethode die Äquivalenzbeziehung realisiert.

So schreiben Sie die Equals-Methode


Die Equals-Methode von Object betrachtet einfach die Adresse, was unseren Anforderungen offensichtlich nicht gerecht werden kann. Wie können wir also sicherstellen, dass wir eine qualitativ hochwertige, logische Vergleichsmethode schreiben, wenn wir die Equals-Methode selbst schreiben? Das Schreiben von equal kann in den folgenden vier Schritten zusammengefasst werden:

1. Verwenden Sie den ==-Operator, um zu prüfen, ob der Parameter nur eine Referenz auf das Objekt ist Wenn die Ergebnisse vorliegen gleich sind, geben Sie true zurück, was darauf hinweist, dass x und y unterschiedliche Verweise auf ein Objekt sind und keine weitere Beurteilung erforderlich ist.

2. Überprüfen Sie mit dem Operator „instanceof“, ob der Parametertyp korrekt ist. Wenn das Ergebnis nicht vom richtigen Typ ist, geben Sie „false“ zurück, da unsere Methode „equals“ vom Objekt erbt Klasse, daher ist der unvermeidbare Typ des Parameters Object. Wir verwenden zunächst die Instanz von, um den Typ der Parameter zu beurteilen. Wenn die Typen nicht korrekt sind, ist kein nächster Beurteilungsschritt erforderlich.

3. Konvertieren Sie die Parameter in den richtigen Typ Da die Erkennung bereits zuvor durchgeführt wurde, gibt es in diesem Schritt kein Problem mit der Typkonvertierung.

4. Beurteilen Sie die Domänenwerte, die in jeder Klasse logisch verglichen werden müssen Nachdem Sie sichergestellt haben, dass x und y unterschiedliche Instanzen desselben Typs sind, bestimmen Sie die Felder, die Der Wert muss zum Vergleich und zur Beurteilung herausgenommen werden. Gibt „true“ zurück, wenn alle korrekt sind, andernfalls „false“.

Wichtige Dinge bei der Implementierung von Equals


Nachdem Sie die Equals-Methode geschrieben haben, müssen Sie wiederholt beurteilen, ob sie Reflexivität, Symmetrie und Transitivität entspricht. Darüber hinaus gibt es einige Dinge, die es zu beachten gilt, wenn man die Methode „equals“ schreibt und gleichzeitig Gleichheit gewährleistet, und hier müssen wir uns verbessern.

Überschreiben Sie immer die HashCode-Methode, wenn Sie die Equals-Methode überschreiben
Wenn wir eine Klasse schreiben, die sich auf Hashing bezieht, müssen wir die HashCode-Methode überschreiben, wenn wir die Equals-Methode überschreiben. Denn in einer Hash-Tabelle sollten logisch identische Objekte den gleichen Hash-Code haben. Um ein relativ einfaches Beispiel zu nennen: Speichern Sie einen String in einem HashSet. Es ist möglich, dass zwei String-Strings mit demselben Inhalt mit == als falsch beurteilt werden, aber nur eine Kopie davon im HashSet vorhanden ist. Dies liegt daran, dass Strings mit derselben Logik denselben HashCode haben.
Wenn Sie die Methode equal für Ihre Klasse überschreiben, beweist dies im Allgemeinen, dass zwei verschiedene Objekte unter bestimmten Umständen logisch gleich sind. Wenn es sich zu diesem Zeitpunkt um Hashing handelt, benötigen die beiden Objekte denselben HashCode. Überschreiben Sie daher beim Überschreiben der Methode „equals“ immer die Methode „hashCode“.

Machen Sie die Equals-Methode nicht zu schlau
Wenn wir zum Schreiben der Equals-Methode einfach dem obigen Implementierungsprozess folgen, entspricht sie den Vorschriften und verursacht keine seltsamen Fehler . Wenn wir jedoch darauf bestehen, verschiedene und ausgefallene Äquivalenzbeziehungen zu verfolgen und den Code aufblähen, wird dies nicht nur die ursprüngliche Absicht einer hohen Kohäsion verletzen, sondern auch einige unerklärliche Fehler im Code verursachen.

Verstehen Sie den Parametertyp der Equals-Methode nicht falsch
Es mag komisch klingen, das zu sagen, aber genau das passiert. Nach dem Ändern des Parametertyps hat die Methode equal nichts mit der Object-Klasse zu tun. Der Compiler meldet keinen Fehler, was den Programmierern nur endlose Kopfschmerzen bereitet. Wenn Sie nicht wissen, dass der Parametertyp „Objekt“ ist, können Sie wahrscheinlich Stunden damit verbringen, sich zu fragen, warum Ihr Programm nicht richtig funktioniert.

Ich habe kürzlich mit meinen Kollegen über den Unterschied zwischen gleich und == gesprochen. Dies ist eigentlich eine sehr alte und einfache Frage, aber wenn Sie die Equals-Methode selbst überschreiben möchten, stellen Sie fest, dass Sie einige Dinge nicht wissen, die Sie aber wissen müssen. Das Abdecken von Gleichberechtigung erfordert viel Aufmerksamkeit. Obwohl Object eine sehr spezifische Klasse ist, besteht ihre Hauptaufgabe darin, sie zu erweitern. Alle seine nicht endgültigen Methoden haben klare universelle Konventionen. Weil sie als überschriebene Methoden konzipiert sind. Jede Klasse, die equal, hashCode, toString, clone und finalize überschreibt, ist für die Einhaltung der allgemeinen Konventionen dieser Methoden verantwortlich. Wenn dies nicht möglich ist, wird es schwierig sein, den gewünschten Effekt zu erzielen, wenn mehrere Klassen kombiniert werden.

Überschreiben Sie nicht die Methode „equals“


Das Überschreiben der Methode „equals“ scheint einfach zu sein, aber es gibt viele überschreibende Methoden, die Fehler verursachen können. Der einfachste Weg, diesen Fehler zu vermeiden, besteht darin, „equals“ nicht zu überschreiben. In diesem Fall ist jede Klasseninstanz nur sich selbst gleich. Unter welchen Umständen können wir uns also dafür entscheiden, die Methode „equals“ nicht zu überschreiben?

Jede Instanz einer Klasse ist von Natur aus einzigartig

Dies gilt für Klassen, die aktive Entitäten und nicht Werte darstellen, wie beispielsweise jede Thread-Instanz. Es ist für uns sinnlos, es mit der Methode „equals“ zu vergleichen, da jeder Thread einzigartig ist. In diesem Fall müssen wir die Methode „equals“ nicht überschreiben, da „equals“ in der Klasse „Object“ völlig ausreicht.

Implementierung der Methode „equals“ in der Object-Klasse:

 public boolean equals(Object obj) { return (this == obj);  }

Ist egal, ob die Klasse eine logische Gleichheitsbeurteilung erfordert

Einige Klassen sind „numerische Klassen“. Der Vergleich von Größen und mathematischen Operationen ist die Aufgabe dieser Klassen. In diesem Fall müssen wir die in der Klasse gespeicherten Werte vergleichen und ein logisches Gleichheitsurteil fällen. Zusätzlich zu den Klassen gibt es in den meisten Klassen nicht das Konzept „ob das eine dem anderen gleich ist“. Solche Klassen, denen die logische Gleichheit egal ist, müssen die Methode equals nicht überschreiben.

Das von der Superklasse implementierte Gleichheitsverfahren ist auf Unterklassen anwendbar.

Zum Beispiel gibt es keinen Unterschied in der Gleichheitsmethode der HashSet-Klasse, die die AbstractSet-Klasse erbt. Dann verwenden Sie direkt HashSet. Verwenden Sie einfach die Gleichheitsmethode von AbstractSet.

Überschreiben Sie die Methode „equals“

Im Gegensatz zu oben müssen wir die Methode „equals“ überschreiben: Wenn die Klasse ihr eigenes Konzept der logischen Gleichheit hat, und der übergeordneten Klasse Es ist keine Überschreibung der Methode „equals“ verfügbar. Zu diesem Zeitpunkt müssen wir es selbst abdecken.

Die Äquivalenzbeziehung der Methode „equals“ in der Sammlung


Die Methode „equals“ implementiert die Äquivalenzbeziehung. Ich habe das Konzept der Äquivalenzbeziehungen in der diskreten Mathematik gelernt. Wenn eine binäre Beziehung auf R die spontane Symmetrie und Transitivität erfüllt, ist sie äquivalent. Lassen Sie uns die Beziehung zwischen Gleichheit und diesen drei Eigenschaften im Detail analysieren.

Reflexivität: Für jeden Nicht-Null-Referenzwert x muss x.equals(x) true zurückgeben

Symmetrie: Für Für jeden nicht -Null-Referenzwerte x und y, genau dann, wenn y.equals(x) true zurückgibt, muss x.equals(y) true zurückgeben

Transitivität: Für alle Für nicht -null Referenzwerte x, y und z, wenn x.equals(y) true zurückgibt und y.equals(z) auch true zurückgibt, dann muss x.equals(z) true zurückgeben.

Reflexivität: ∀ a ∈A, => (a, a) ∈ R
Symmetrie: (a, b) ∈R∧ a ≠ b => 🎜> Transitivität: (a, b)∈R, (b, c)∈R => (a, c)∈R

Der Vergleich dieser drei Eigenschaften ist kein Problem. Es ist ersichtlich, dass die Gleichheitsmethode die Äquivalenzbeziehung realisiert.

So schreiben Sie die Equals-Methode


Die Equals-Methode von Object betrachtet einfach die Adresse, was unseren Anforderungen offensichtlich nicht gerecht werden kann. Wie können wir also sicherstellen, dass wir eine qualitativ hochwertige, logische Vergleichsmethode schreiben, wenn wir die Equals-Methode selbst schreiben? Das Schreiben von equal kann in den folgenden vier Schritten zusammengefasst werden:

1. Verwenden Sie den ==-Operator, um zu prüfen, ob der Parameter nur eine Referenz auf das Objekt ist Wenn die Ergebnisse vorliegen gleich sind, geben Sie true zurück, was darauf hinweist, dass x und y unterschiedliche Verweise auf ein Objekt sind und keine weitere Beurteilung erforderlich ist.

2. Überprüfen Sie mit dem Operator „instanceof“, ob der Parametertyp korrekt ist. Wenn das Ergebnis nicht vom richtigen Typ ist, geben Sie „false“ zurück, da unsere Methode „equals“ vom Objekt erbt Klasse, also der unvermeidbare Typ des Parameters. Wir verwenden zunächst die Instanz von, um den Typ der Parameter zu beurteilen. Wenn die Typen nicht korrekt sind, ist der nächste Beurteilungsschritt nicht erforderlich.

3. Konvertieren Sie die Parameter in den richtigen Typ Da die Erkennung bereits zuvor durchgeführt wurde, gibt es in diesem Schritt kein Problem mit der Typkonvertierung.

4. Beurteilen Sie die Domänenwerte, die in jeder Klasse logisch verglichen werden müssen Nachdem Sie sichergestellt haben, dass x und y unterschiedliche Instanzen desselben Typs sind, bestimmen Sie die Felder, die Der Wert muss zum Vergleich und zur Beurteilung herausgenommen werden. Gibt true zurück, wenn alle korrekt sind, andernfalls false.

Wichtige Dinge bei der Implementierung von Equals


Nachdem Sie die Equals-Methode geschrieben haben, müssen Sie wiederholt beurteilen, ob sie Reflexivität, Symmetrie und Transitivität entspricht. Darüber hinaus gibt es einige Dinge, die es zu beachten gilt, wenn man die Methode „equals“ schreibt und gleichzeitig Gleichheit gewährleistet, und hier müssen wir uns verbessern.

Überschreiben Sie immer die HashCode-Methode, wenn Sie die Equals-Methode überschreiben
Wenn wir eine Klasse schreiben, die sich auf Hashing bezieht, müssen wir die HashCode-Methode überschreiben, wenn wir die Equals-Methode überschreiben. Denn in einer Hash-Tabelle sollten logisch identische Objekte den gleichen Hash-Code haben. Um ein relativ einfaches Beispiel zu nennen: Speichern Sie einen String in einem HashSet. Es ist möglich, dass zwei String-Strings mit demselben Inhalt mit == als falsch beurteilt werden, aber nur eine Kopie davon im HashSet vorhanden ist. Dies liegt daran, dass Strings mit derselben Logik denselben HashCode haben.
Wenn Sie die Methode equal für Ihre Klasse überschreiben, beweist dies im Allgemeinen, dass zwei verschiedene Objekte unter bestimmten Umständen logisch gleich sind. Wenn es sich zu diesem Zeitpunkt um Hashing handelt, benötigen die beiden Objekte denselben HashCode. Überschreiben Sie daher beim Überschreiben der Methode „equals“ immer die Methode „hashCode“.

Machen Sie die Equals-Methode nicht zu schlau
Wenn wir zum Schreiben der Equals-Methode einfach dem obigen Implementierungsprozess folgen, entspricht sie den Vorschriften und verursacht keine seltsamen Fehler . Wenn wir jedoch darauf bestehen, verschiedene und ausgefallene Äquivalenzbeziehungen zu verfolgen und den Code aufblähen, wird dies nicht nur die ursprüngliche Absicht einer hohen Kohäsion verletzen, sondern auch einige unerklärliche Fehler im Code verursachen.

Verstehen Sie den Parametertyp der Equals-Methode nicht falsch
Es mag komisch klingen, das zu sagen, aber genau das passiert. Nach dem Ändern des Parametertyps hat die Methode equal nichts mit der Object-Klasse zu tun. Der Compiler meldet keinen Fehler, was den Programmierern nur endlose Kopfschmerzen bereitet. Wenn Sie nicht wissen, dass der Parametertyp „Objekt“ ist, können Sie wahrscheinlich Stunden damit verbringen, sich zu fragen, warum Ihr Programm nicht richtig funktioniert.

Das obige ist der detaillierte Inhalt vonEin Überblick über die tiefergehenden Methoden zum Überschreiben von Equals in Java. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

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