2010-11-14 9 views
85

sagen, dass ich meine eigene KlasseWie Standard .equals und .hashCode wird für meine Klassen funktionieren?

public class MyObj { /* ... */ } 

Es hat einige Attribute und Methoden. Es implementiert NICHT gleich, implementiert nicht HashCode.

Sobald wir gleich und hashCode aufrufen, was sind die Standardimplementierungen? Aus Objektklasse? Und was sind sie? Wie funktioniert der Standard equals? Wie funktioniert der Standard-HashCode und was kommt zurück? == prüft nur, ob sie auf dasselbe Objekt verweisen, also ist es einfach, aber was ist mit den Methoden equals() und hashCode()?

Antwort

77

Ja, die Standardimplementierung ist Object's (allgemein gesprochen; wenn Sie von einer Klasse erben, die equals und/oder hashCode neu definiert hat, verwenden Sie stattdessen diese Implementierung).

Aus der Dokumentation:

equals

Die Methode equals für Object-Klasse implementiert die kritischste möglich ¨Aquivalenzrelation auf Objekte; Das heißt, für alle Nicht-Null-Referenzwerte x und y gibt diese Methode true zurück, wenn und nur wenn sich x und y auf dasselbe Objekt beziehen (x == y hat den Wert true).

hashCode

So viel wie vernünftigerweise praktikabel ist, kehrt die Methode hashCode nach Klasse Object definierte verschiedene ganze Zahlen für verschiedene Objekte. (Dies wird in der Regel durch Umwandlung der internen Adresse des Objekts in eine ganze Zahl durchgeführt, aber diese Implementierungstechnik ist nicht von der JavaTM-Programmiersprache erforderlich.)

+0

Link funktioniert nicht –

+0

@RameshPapaganti Danke für die Köpfe, es ist behoben! –

0

IBMs developerworks sagt:

Unter dieser Standardimplementierung, zwei Referenzen gleich sind nur dann, wenn sie auf die exakt gleiche Objekt beziehen . In ähnlicher Weise wird die Standardimplementierung von hashCode(), die von Object bereitgestellt wird, abgeleitet, indem die Speicheradresse des Objekts auf einen ganzzahligen Wert abgebildet wird.

jedoch sicher sein über die genauen Details der Implementierung für einen bestimmten Version von Java-Anbieter ist es wahrscheinlich am besten als die Quelle zu suchen (wenn es verfügbar ist)

1

Ja, von Object Klasse, da der Klasse implizit Objekt erstreckt . equals gibt einfach this == obj zurück. hashCode Implementierung ist nativ. Nur eine Vermutung - es gibt den Zeiger auf das Objekt zurück.

+2

Es ist ein Zeiger auf das Objekt im Speicher, aber es ist keine Speicheradresse des Objekts. Der GC kann das Objekt im Speicher bewegen und der Hash-Code bleibt gleich. – Jeremy

+0

@ Jeremy Danke. http://stackoverflow.com/questions/2427631/how-is-hashcode-calculated-in-java kann interessant sein. – khachik

39

Von Object in einer der JVM-Implementierungen:

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

public int hashCode() { 
    return VMMemoryManager.getIdentityHashCode(this); 
} 

In beiden Fällen wird nur die Speicheradresse der betreffenden Objekte verglichen.

+7

Aus welcher Version von JDK stammt? In 'v6u23 ea':' public nativ int hashCode(); ' – khachik

+0

@ kha - Sie haben recht, ich glaube, ich habe eine der nativen Implementierungen ausfindig gemacht, um zu sehen, was es tatsächlich tat –

9

Es gibt Standardimplementierungen von equals() und hashCode() in Object.Wenn Sie keine eigene Implementierung bereitstellen, werden diese verwendet. Für equals() bedeutet dies einen Vergleich ==: die Objekte sind nur dann gleich, wenn sie genau das gleiche Objekt sind. Für hashCode() hat die Javadoc eine gute Erklärung.

Weitere Informationen finden Sie Effective Java, Chapter 3 (pdf), Punkt 8.

1

Wenn Sie Ihre eigene Implementierung nicht liefern, ein von Object abgeleitet werden würde. Es ist OK, es sei denn, Sie planen, Ihre Klasseninstanzen in hashSet (jede Sammlung, die tatsächlich hashCode() verwendet) oder etwas, das die Gleichheit des Objekts überprüfen muss (d. H. Die Methode contains() von HashSet). Sonst funktioniert es nicht richtig, wenn Sie danach fragen.

Es ist ziemlich einfach, Ihre eigene Implementierung dieser Methoden dank HashCodeBuilder und EqualsBuilder von Apache Commons Lang bereitzustellen.

+0

(a) Warum sagen Sie das Objekt Die Standardimplementierung von 'equals' funktioniert nicht korrekt mit HashSet? Das widerspricht den anderen Antworten auf dieser Seite. (b) Danke für die Commons Lang-Links. –

+1

@Basil: Ich glaube nicht, dass das widerspricht. Natürlich würde die Standardimplementierung funktionieren ... irgendwie, aber nicht so, wie Sie es erwarten. Das heißt, da equals() eine Bezugsgleichheit verwendet, wären zwei ansonsten identische Objekte in den Augen der Standardimplementierung "verschieden". Als Ergebnis haben Sie möglicherweise zwei verschiedene Instanzen des gleichen Objekts in Ihrem Set. Die typische Verwendung von Sets ist, wenn Duplikate entfernt werden sollen ... –

+0

@ PawełDyda: Das Standardverhalten ist im Allgemeinen für veränderbare Typen korrekt. Wenn "Foo" und "Bar" Verweise auf zwei verschiedene Instanzen eines veränderbaren Typs sind und eine Methode (zB 'SomeMutingMethod') existiert, so dass 'Foo.SomeMutingMethod()' 'Bar' nicht auf die gleiche Weise beeinflusst 'Foo', dieser Unterschied sollte ausreichen, um die Objekte als ungleich zu betrachten. – supercat