JavaRush /Java-Blog /Random-DE /Arbeiten mit den Methoden hashCode() und equal() in Java
Lenchik854
Level 0
Chernihiv

Arbeiten mit den Methoden hashCode() und equal() in Java

Veröffentlicht in der Gruppe Random-DE
In diesem Beitrag werde ich mein Verständnis der Methoden hashCode()und darlegen equals(). Ich möchte über ihre Standardimplementierung sprechen und darüber, wie man sie korrekt überschreibt. Ich werde auch über die Implementierung dieser Methoden mithilfe der Hilfsklassen des Apache Common-Pakets schreiben. Arbeiten mit den Methoden hashCode() und equal() in Java - 1Inhalt dieses Beitrags:
  1. Verwenden hashCode()von und equals().
  2. Standardverhalten überschreiben.
  3. Überschreiben hashCode()und equals()Verwenden von Apache Commons Lang.
  4. Etwas, an das man sich unbedingt erinnern sollte.
  5. Besondere Aufmerksamkeit bei der Verwendung von ORM.
Die Methoden hashCode()und equals()wurden in der Klasse definiert Object, die die übergeordnete Klasse für Java-Objekte ist. Daher erben alle Java-Objekte die Standardimplementierung dieser Methoden.

Verwendung von hashCode() und equal()

Die Methode hashCode()wird verwendet, um eine eindeutige Ganzzahl für ein bestimmtes Objekt zu erhalten. Wenn ein Objekt als Datenstruktur in einer Hash-Tabelle (auch Bucket genannt) gespeichert werden muss, wird diese Nummer verwendet, um seine Position in dieser Tabelle zu bestimmen. Standardmäßig gibt die Methode hashCode()für ein Objekt die Nummer des Speicherorts zurück, an dem das Objekt gespeichert ist. Die Methode equals()dient, wie der Name schon sagt, einfach dazu, die Gleichheit zweier Objekte zu überprüfen. Die Standardimplementierung dieser Methode überprüft einfach die Referenzen zweier Objekte, um festzustellen, ob sie gleichwertig sind.

Überschreiben des Standardverhaltens

Alles funktioniert einwandfrei, solange Sie keine dieser Methoden in Ihren Klassen überschreiben. Manchmal müssen Anwendungen jedoch das Standardverhalten einiger Objekte ändern. Nehmen wir ein Beispiel, bei dem Sie eine Employee. Schreiben wir die minimal mögliche Struktur einer solchen Klasse.
public class Employee
{
    private Integer id;
    private String firstname;
    private String lastName;
    private String department;

    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }
    public String getFirstname() {
        return firstname;
    }
    public void setFirstname(String firstname) {
        this.firstname = firstname;
    }
    public String getLastName() {
        return lastName;
    }
    public void setLastName(String lastName) {
        this.lastName = lastName;
    }
    public String getDepartment() {
        return department;
    }
    public void setDepartment(String department) {
        this.department = department;
    }
}
Die oben beschriebene Klasse Employeeverfügt über einige grundlegende Attribute und Zugriffsmethoden. Schauen wir uns nun eine einfache Situation an, in der wir zwei Objekte der Klasse vergleichen müssen Employee.
public class EqualsTest {
    public static void main(String[] args) {
        Employee e1 = new Employee();
        Employee e2 = new Employee();

        e1.setId(100);
        e2.setId(100);
        //Печатает false в консоли
        System.out.println(e1.equals(e2));
    }
}
Man muss kein Hellseher sein, um zu erraten, dass die obige Methode „falsch“ zurückgibt. Aber ist das tatsächlich richtig, wenn man bedenkt, dass es sich bei diesen beiden Objekten um dasselbe handelt? Bei Echtzeitanwendungen muss die Methode „true“ zurückgeben. Um das richtige Verhalten zu erreichen, müssen wir die Methode equals()wie folgt überschreiben:
public boolean equals(Object o) {
        if(o == null)
        {
            return false;
        }
        if (o == this)
        {
           return true;
        }
        if (getClass() != o.getClass())
        {
            return false;
        }
        Employee e = (Employee) o;
        return (this.getId() == e.getId());
}
Fügen Sie diese Methode zu Ihrer Klasse hinzu Employeeund die Äquivalenzprüfung gibt „true“ zurück. Aber haben wir alles getan? Noch nicht. Lassen Sie uns unsere modifizierte Klasse noch einmal testen.
import java.util.HashSet;
import java.util.Set;

public class EqualsTest
{
    public static void main(String[] args)
    {
        Employee e1 = new Employee();
        Employee e2 = new Employee();

        e1.setId(100);
        e2.setId(100);

        //Печатает 'true'
        System.out.println(e1.equals(e2));

        Set employees = new HashSet();
        employees.add(e1);
        employees.add(e2);
        //Печатает два ein Objektа
        System.out.println(employees);
    }
}
Der Befehl System.out.println(employee)druckt zwei Objekte. Wenn beide Objekte gleichwertig wären und Setnur eindeutige Objekte darin enthalten wären, dann HashSetsollte es darin nur eine Instanz geben, d. h. Beide Objekte verweisen auf dieselben Instanzen der Klasse Employee. Was haben wir verpasst? Wir haben die zweite wichtige Methode verpasst hashCode(). Wie es in der Java-Dokumentation heißt, equals()müssen Sie die Methode überschreiben, wenn Sie sie überschreiben hashCode(). Fügen wir unserer Klasse also eine weitere Methode hinzu Employee.
@Override
 public int hashCode()
 {
    final int PRIME = 31;
    int result = 1;
    result = PRIME * result + getId();
    return result;
 }
Wir haben diese Methode einmal zu unserer Klasse hinzugefügt, und es wird nur ein Objekt gedruckt. Die Überprüfung der Äquivalenz von e1 und e2 ergab daher „true“.

Überschreiben hashCode()und equals()Verwenden von Apache Commons Lang

Apache Commons bietet zwei großartige Hilfsklassen zum Aufrufen von Methoden hashCode()und equals(). Unten sehen wir die Verwendung:
import org.apache.commons.lang3.builder.EqualsBuilder;
import org.apache.commons.lang3.builder.HashCodeBuilder;
public class Employee
{
 private Integer id;
 private String firstname;
 private String lastName;
 private String department;
public Integer getId() {
    return id;
 }
 public void setId(Integer id) {
    this.id = id;
 }
 public String getFirstname() {
    return firstname;
 }
 public void setFirstname(String firstname) {
    this.firstname = firstname;
 }
 public String getLastName() {
    return lastName;
 }
 public void setLastName(String lastName) {
    this.lastName = lastName;
 }
 public String getDepartment() {
    return department;
 }
 public void setDepartment(String department) {
    this.department = department;
 }
@Override
 public int hashCode()
 {
    final int PRIME = 31;
    return new HashCodeBuilder(getId()%2==0?getId()+1:getId(), PRIME).
           toHashCode();
 }
@Override
 public boolean equals(Object o) {
    if (o == null)
       return false;
    if (o == this)
       return true;
    if (o.getClass() != getClass())
       return false;
    Employee e = (Employee) o;
       return new EqualsBuilder().
              append(getId(), e.getId()).
              isEquals();
    }
 }
Wenn Sie hingegen einen der Code-Editoren verwenden, sollten diese auch in der Lage sein, einige schöne Strukturen für Sie aufzurufen. Wenn Sie beispielsweise in der Eclipse-IDE mit der rechten Maustaste auf Klasse >> Quelle > HashCode() und Equals() generieren ... klicken , wird eine sehr schöne Implementierung für Sie generiert. Arbeiten mit den Methoden hashCode() und equal() in Java - 2Etwas, an das man sich unbedingt erinnern sollte.
  1. Verwenden Sie immer dieselben Objektattribute, um sowohl und hashCode()als auch aufzurufen equals(). Nur in unserem Fall haben wir verwendet employee id.
  2. Die Methode equals()muss persistent sein (wenn sich das Objekt nicht geändert hat, muss die Methode denselben Wert zurückgeben).
  3. Wann immer a.equals(b), dann a.hashCode()muss dasselbe sein wie b.hashCode().
  4. Wenn Sie eine Methode überschreiben, müssen Sie auch die zweite überschreiben.

Besondere Aufmerksamkeit bei der Verwendung von ORM

Wenn Sie mit ORM arbeiten (ru.wikipedia.org/wiki/ORM), verwenden Sie immer Getter und niemals Feldreferenzen hashCode(). equals()Dies liegt daran, dass in einem ORM von Zeit zu Zeit Felder mit Lazy Load geladen werden und erst dann darauf zugegriffen werden kann, wenn ihre Getter aufgerufen werden. EmployeeIn unserer Klasse verwenden wir beispielsweise e1.id == e2.id. Es ist durchaus möglich, dass die id-Felder mithilfe von Lazy Loading geladen werden. Eines der Felder kann 0 oder null sein und wir erhalten ein falsches Verhalten. Aber wenn , verwendet wird e1.getId() == e2.getId(), können wir sicher sein, auch wenn die Felder mit Lazy Loading geladen wurden; Wenn Sie den Getter aufrufen, wird zuerst das Feld gefüllt. Das ist alles, was ich über die hashCode()und- Methoden weiß equals(). Ich hoffe, das hilft jemandem irgendwo. Viel Erfolg beim Studium!! ps Dies ist mein erster Übersetzungsversuch. Ich habe versucht, alles so nah wie möglich an dem zu vermitteln, was der Autor sagen wollte. Wenn Sie Anmerkungen haben, schreiben Sie diese bitte in die Kommentare. Urteilen Sie nicht streng :-))) Originalartikel
Kommentare
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION