Dieses Dokument ist ein Nachdruck des Materials, das vor etwa 10 Jahren für neue Ingenieure erstellt wurde. Einige altmodische Teile wie API und Syntax mögen auffallen, aber sobald Sie die Idee kennen, beabsichtige ich, die grundlegenden Teile zu organisieren, die für eine lange Zeit verwendet werden können, und hoffe, dass sie jetzt für junge Ingenieure hilfreich sein werden.
Angenommen, die Benutzerklasse ist wie unten gezeigt vorhanden, lesen Sie weiter. Die Benutzerklasse behält ihre ID und ihren Namen als internen Status bei.
User.java
class User {
/** ID */
private int id;
/**Name*/
private String name;
/**
*Es ist ein Konstruktor.
*
* @param id ID
* @Param Name Name
*/
public User(int id, String name) {
this.id = id;
this.name = name;
}
//Unten weggelassen
}
User user1 = new User(1, "Tanaka");
User user2 = user1;
Benutzer1 und Benutzer2 enthalten Verweise auf dasselbe Objekt. Daher sind die Objekte, auf die Benutzer1 und Benutzer2 verweisen, "identisch".
User user3 = new User(1, "Tanaka");
User user4 = new User(2, "Suzuki");
User user5 = new User(1, "Suzuki");
Benutzer3 und Benutzer5 haben dieselbe ID. Benutzer4 und Benutzer5 haben denselben Namen.
Daher sind Benutzer3 und Benutzer5 Objekte mit dem ID-Wert "gleicher Wert". Benutzer4 und Benutzer5 sind Objekte mit "gleichen Werten" in ihren Namenswerten.
Die Objektäquivalenz muss vom Programmierer selbst gemäß den Geschäftsregeln implementiert werden.
Die Objektäquivalenz wird in der Methode equals der entsprechenden Klasse definiert.
Wenn es eine Regel gibt, mit der die Äquivalenz des Benutzerklassenobjekts im ID-Wert beurteilt werden kann, beschreiben Sie den Prozess zum Vergleichen des ID-Werts in der Methode equals.
Wenn es eine Regel gibt, mit der die Äquivalenz des Objekts der Benutzerklasse im Namenswert beurteilt werden kann, beschreiben Sie den Prozess zum Vergleichen des Namenswerts in der Methode equals.
Die Objektidentität wird vom Vergleichsoperator "==" bestimmt. Da Benutzer1 und Benutzer2 oben dasselbe Objekt sind
user1 == user2 // ⇒ true
Das Ergebnis von ist "wahr".
Weil Benutzer3, Benutzer4 und Benutzer5 unterschiedliche Objekte sind
user3 == user4 // ⇒ false
user3 == user5 // ⇒ false
user4 == user5 // ⇒ false
Das Ergebnis von ist alles "falsch".
Die Gleichheit von Objekten wird mit der in jeder Klasse implementierten "Gleichheits" -Methode verglichen.
Wenn die equals-Methode der User-Klasse mit ID als Vergleichsbedingung implementiert ist, lautet das Ergebnis der equals-Methode wie folgt.
user3.equals(user4) // ⇒ false
user3.equals(user5) // ⇒ true
user4.equals(user5) // ⇒ false
Wenn die equals-Methode der User-Klasse mit dem Namen als Vergleichsbedingung implementiert ist, lautet das Ergebnis der equals-Methode wie folgt.
user3.equals(user4) // ⇒ false
user3.equals(user5) // ⇒ false
user4.equals(user5) // ⇒ true
Implementieren Sie die equals-Methode in der User-Klasse wie folgt, um die Objektäquivalenz der Benutzerklasse anhand der ID zu bestimmen.
User.java
/**
*Die Instanz dieser Klasse und das Objekt wurden als Argument übergeben
*Gibt true zurück, wenn sie gleich sind.
*Das als Argument übergebene Objekt ist eine Instanz der User-Klasse
*Wenn die ID-Werte gleich sind, werden sie als gleich betrachtet.
*
* @True, wenn das im return-Argument übergebene Objekt eine Instanz der User-Klasse ist und die IDs gleich sind.
*/
public boolean equals(Object other) {
if (this == other) { //True, wenn das im Argument übergebene Objekt dieses Objekt selbst war
return true;
}
if (!(other instanceof User)) { //Das als Argument übergebene Objekt ist ein Objekt der User-Klasse
return false; //Falsch wenn nicht.
}
User otherUser = (User) other;
if (this.id == otherUser.getId()) { //Vergleichen Sie die ID-Werte, true wenn gleich, false wenn nicht gleich.
return true;
}
return false;
}
Implementieren Sie die equals-Methode in der User-Klasse wie folgt, um die Objektäquivalenz der Benutzerklasse anhand des Namens zu bestimmen.
Der Rest des Prozesses ist der gleiche, nur der Wertevergleich ändert sich von id zu name.
User.java
/**
*Die Instanz dieser Klasse und das Objekt wurden als Argument übergeben
*Gibt true zurück, wenn sie gleich sind.
*Das als Argument übergebene Objekt ist eine Instanz der User-Klasse
*Wenn die Werte von name gleich sind, werden sie als gleich angesehen.
*
* @True, wenn das im return-Argument übergebene Objekt eine Instanz der User-Klasse ist und die Namen gleich sind.
*/
public boolean equals(Object other) {
if (this == other) {
return true;
}
if (!(other instanceof User)) {
return false;
}
User otherUser = (User) other;
if (this.name.equals(otherUser.getName())) {
return true;
}
return false;
}
Wenn Sie die Methode equals implementieren, müssen Sie auch die Methode hashCode implementieren. Die hashCode-Methode wird gemäß den folgenden Regeln implementiert.
Wenn Sie in der User-Klasse die equals-Methode implementieren, die die Gleichheit basierend auf dem ID-Wert ermittelt, wird die hashCode-Methode als Beispiel wie folgt implementiert.
User.java
/**
*Gibt den Hash-Code zurück.
*
* @Rückgabe des Hash-Werts einer Instanz dieser Klasse
*/
public int hashCode() {
return this.id;
}
Da die equals-Methode die Äquivalenz basierend auf dem ID-Wert bestimmt, gibt die hashCode-Methode des Objekts, dessen ID-Werte gleich sind, dh die equals-Methode gibt true zurück, denselben Wert durch die obige Implementierung zurück. Es kann gesagt werden, dass die Verarbeitung der obigen hashCode-Methode für die obige Regel geeignet ist.
User.java
/**
*Gibt den Hash-Code zurück.
*
* @Rückgabe des Hash-Werts einer Instanz dieser Klasse
*/
public int hashCode() {
return 0;
}
Die Verarbeitung der obigen hashCode-Methode ist tatsächlich gültig. Der Hashcode für alle Objekte gibt 0 zurück. Das heißt, alle Objekte, für die die Methode equals true ist, geben denselben Wert (0) wie der Rückgabewert hashCode zurück. Die obige Implementierung wird auch im Lichte der Regeln der hashCode-Implementierung als in Ordnung angesehen, da Objekte, deren equals-Methode nicht true ist (das Ergebnis des Aufrufs der equals-Methode ist false), dieselbe hashCode-Methode zurückgeben können. ..
Die Implementierung in Beispiel 2 wird jedoch nicht empfohlen. Wenn Sie hashCode implementieren, implementieren Sie es mindestens wie in Beispiel 1.
Wenn Sie einer Instanz einer Klasse, die einen Hash-Algorithmus verwendet (HashMap, HashSet usw.), ein Objekt hinzufügen, das hashCode nicht korrekt implementiert, wird das erwartete Verhalten nicht erhalten.
Es ist ein Algorithmus, der die Verarbeitung rationalisiert, indem der Hash-Wert beim Speichern und Suchen nach Objekten im Voraus berechnet wird und Objekte basierend auf dem erhaltenen Hash-Wert gespeichert und gesucht werden.
Um den Hash-Algorithmus zu verstehen, empfiehlt es sich, die Verhaltensunterschiede zwischen ArrayList und HashSet zu vergleichen.
ArrayList und HashSet sind beide Klassen, die die Collection-Schnittstelle implementieren, weisen jedoch die folgenden Verhaltensunterschiede auf. (HashSet implementiert einen Hash-Algorithmus.)
ArrayList speichert und hält die hinzugefügten Elemente in einer einspaltigen Liste. Beim Abrufen der gespeicherten Elemente wird die Methode equals des Objekts in der Reihenfolge vom Anfang der Liste aufgerufen, und das Element, für das das Ergebnis des Methodenaufrufs equals true ist, wird als Rückgabewert zurückgegeben.
⇒ Wenn die Anzahl der Elemente in der Liste sehr groß ist und sich das Element, das Sie abrufen möchten, hinter der Liste befindet, kann sich die Sucheffizienz erheblich verschlechtern.
HashSet speichert und ruft die hinzugefügten Elemente gemäß dem folgenden Verfahren ab.
Da die Elemente im Voraus basierend auf hashCode in "Räume" klassifiziert und gespeichert werden, muss beim Vergleichen von Objekten nur eine begrenzte Anzahl von Objekten verglichen werden, was die Sucheffizienz verbessert.
Wenn hashCode nicht korrekt implementiert ist, kann es vorkommen, dass das Zielobjekt nicht gefunden wird, da es in einem anderen Raum nach dem Zielobjekt sucht, obwohl die Objekte denselben Wert haben.
Wenn hashCode implementiert ist, um 0 zurückzugeben, werden alle Objekte im "Raum" mit der tatsächlichen Raumnummer 0 gespeichert, und der Algorithmus entspricht dem Hinzufügen eines Elements zu ArrayList, was den Vorteil des Hash-Algorithmus hat. Ich kann es nicht verstehen
Die Methoden equals und hashCode sind ursprünglich in der Object-Klasse implementiert.
Die Object-Klasse ist eine Oberklasse aller Klassen. Wenn Sie die Methode equals oder hashCode für eine Instanz einer Klasse aufrufen, die die Methoden equals und hashCode nicht implementiert, wird sie daher in der übergeordneten Object-Klasse definiert (sofern keine andere erbende Klasse vorhanden ist). Die Methode equals und die Methode hashCode werden aufgerufen.
Wenn beispielsweise die Methode equals für eine Instanz einer Klasse aufgerufen wird, die die Methode equals nicht implementiert, lautet die Reihenfolge des Aufrufs der Methoden wie folgt.
"Implementieren der Methode equals und der Methode hashCode" bedeutet (wenn keine andere Klasse zu erben ist)
Es bedeutet das.
Die in der Objektklasse definierte Methode equals bestimmt die "Objektäquivalenz" basierend auf der "Objektidentität".
Wenn Sie die equals-Methode in der User-Klasse nicht implementieren (wenn Sie die equals-Methode in der Object-Klasse nicht überschreiben), gilt die equals-Methode, wenn die Instanz in der User-Klasse weder eine ID noch ein Name ist und die Instanzen genau gleich sind. Wird wahr zurückkehren.
//Verhalten der Methode der Objektklasse gleich
Object obj1 = new Object();
Object obj2 = new Object();
Object obj3 = obj1;
obj1 == obj2; // false
obj2 == obj3; // false
obj1 == obj3; // true
// "=="Vergleich und Ergebnisse sind gleich
obj1.equals(obj2); // false
obj2.equals(obj3); // false
obj1.equals(obj3); // true
//Verhalten der Benutzerklasse, die keine Methode equals implementiert
// (Da die in der Object-Klasse definierte Methode equals aufgerufen wird, ist das Verhalten dasselbe.)
User user1 = new User();
User user2 = new User();
User user3 = user1;
user1 == user2; // false
user2 == user3; // false
user1 == user3; // true
user1.equals(user2); // false
user2.equals(user3); // false
user1.equals(user3); // true
Recommended Posts