Überschreiben der Methode „equals“ oder Erstellen einer neuen Methode

StackOverflow https://stackoverflow.com/questions/16557

  •  08-06-2019
  •  | 
  •  

Frage

Ich habe immer gedacht, dass die Methode .equals() in Java überschrieben werden sollte, um sie spezifisch für die von Ihnen erstellte Klasse zu machen.Mit anderen Worten: Suchen Sie nach der Äquivalenz zweier verschiedener Instanzen und nicht nach zwei Verweisen auf dieselbe Instanz.Ich bin jedoch auf andere Programmierer gestoßen, die offenbar der Meinung sind, dass das Standardobjektverhalten beibehalten und eine neue Methode zum Testen der Äquivalenz zweier Objekte derselben Klasse erstellt werden sollte.

Welche Argumente sprechen für und gegen das Überschreiben der Methode „equals“?

War es hilfreich?

Lösung

Das Überschreiben der Methode „equals“ ist erforderlich, wenn Sie die Äquivalenz in Standardbibliotheksklassen testen möchten (z. B. um sicherzustellen, dass ein java.util.Set eindeutige Elemente enthält oder um Objekte als Schlüssel in java.util.Map-Objekten zu verwenden).

Beachten Sie: Wenn Sie „equals“ überschreiben, stellen Sie sicher, dass Sie den API-Vertrag einhalten, wie in der Dokumentation beschrieben.Stellen Sie beispielsweise sicher, dass Sie auch überschreiben Object.hashCode:

Wenn zwei Objekte gemäß der Equals (Object) -Methode gleich sind, muss das Aufrufen der HashCode -Methode für jedes der beiden Objekte das gleiche Ganzzahlergebnis erzielen.

BEARBEITEN:Ich habe dies nicht als vollständige Antwort zu diesem Thema gepostet, daher werde ich Fredrik Kalseths Aussage wiederholen, dass das Überschreiben von Gleichheit am besten funktioniert unveränderliche Objekte.So zitieren Sie die API für Karte:

Notiz:Es muss großer Sorgfalt ausgeübt werden, wenn veränderliche Objekte als Kartenschlüssel verwendet werden.Das Verhalten einer Karte ist nicht spezifiziert wenn der Wert eines Objekts geändert wird in einer Weise, die sich auf Gleichgestellte auswirkt vergleiche, während das Objekt ein Schlüssel ist in der Karte.

Andere Tipps

Ich würde wärmstens empfehlen, sich ein Exemplar von Effective Java zu besorgen und Punkt 7 unter Beachtung der Richtlinien durchzulesen entspricht Vertrag.Sie müssen vorsichtig sein, wenn Sie „equals“ für veränderliche Objekte überschreiben, da viele Sammlungen wie „Maps“ und „Sets“ „equals“ verwenden, um die Äquivalenz zu bestimmen, und die Mutation eines in einer Sammlung enthaltenen Objekts zu unerwarteten Ergebnissen führen kann.Brian Goetz hat auch ein ziemlich gutes Übersicht über die Implementierung von equal und hashCode.

Sie sollten „nie“ „equals“ und „getHashCode“ für veränderliche Objekte überschreiben – dies gilt sowohl für .net als auch für Java.Wenn Sie dies tun, verwenden Sie ein solches Objekt als Schlüssel in z. B. einem Wörterbuch und dann ändern Wenn Sie dieses Objekt nicht finden, geraten Sie in Schwierigkeiten, da das Wörterbuch auf den Hashcode angewiesen ist, um das Objekt zu finden.

Hier ist ein guter Artikel zum Thema: http://weblogs.asp.net/bleroy/archive/2004/12/15/316601.aspx

@David Schlösnagle Erwähnungen erwähnt Josh Blochs Effektives Java -- das ist ein muss lesen für jeden Java-Entwickler.

Es gibt ein verwandtes Problem:Bei Objekten mit unveränderlichem Wert sollten Sie auch das Überschreiben in Betracht ziehen compare_to.Der Standardwortlaut für den Fall, dass sie sich unterscheiden, ist in der Vergleichbare API:

Es ist im Allgemeinen der Fall, aber nicht unbedingt erforderlich, dass (compare(x, y)==0) == (x.equals(y)).Im Allgemeinen sollte jeder Vergleicher, der gegen diese Bedingung verstößt, diesen Umstand deutlich angeben.Die empfohlene Sprache ist „Hinweis:Dieser Komparator erzwingt Ordnungen, die nicht mit Gleichen vereinbar sind.

Die Equals-Methode dient zum Vergleichen von Referenzen.Daher sollte es nicht außer Kraft gesetzt werden, um sein Verhalten zu ändern.

Sie sollten bei Bedarf eine neue Methode erstellen, um die Äquivalenz in verschiedenen Instanzen zu testen (oder in einigen .NET-Klassen die CompareTo-Methode verwenden).

Ehrlich gesagt gibt es in Java kein wirkliches Argument gegen das Überschreiben gleicht.Wenn Sie Instanzen auf Gleichheit vergleichen müssen, dann tun Sie das.

Wie oben erwähnt, müssen Sie den Vertrag mit kennen Hash-Code, und achten Sie auch auf die Fallstricke rund um das Vergleichbar Schnittstelle - in fast allen Situationen möchten Sie das natürliche Ordnung wie durch Vergleichbar definiert ist im Einklang mit Gleichen (siehe die BigDecimal API-Dokument für das kanonische Gegenbeispiel)

Das Erstellen einer neuen Methode zur Entscheidung über Gleichheit widerspricht in gewisser Weise den Java-Konventionen, abgesehen davon, dass sie nicht mit den vorhandenen Bibliotheksklassen arbeitet.

Sie sollten nur das überschreiben müssen equals() -Methode, wenn Sie beim Hinzufügen von Objekten zu sortierten Datenstrukturen ein bestimmtes Verhalten wünschen (SortedSet usw.)

Wenn Sie das tun, sollten Sie auch überschreiben hashCode().

Sehen Hier für eine vollständige Erklärung.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top