JavaRush /Java-Blog /Random-DE /Überladen der Methoden equal() und hashCode() in Java
Coder
Level 17

Überladen der Methoden equal() und hashCode() in Java

Veröffentlicht in der Gruppe Random-DE

Überschreiben der Methoden equal() und hashCode() in Java

Equalsund hashCodesind die grundlegenden Methoden, die in der Klasse deklariert Objectund in den Standard-Java-Bibliotheken enthalten sind. Überladen der Methoden equal() und hashCode() in Java - 1Die Methode еquals()wird verwendet, um Objekte zu vergleichen und hashCodeeinen ganzzahligen Code für das Objekt zu generieren. Diese Methoden werden in den Java-Standardbibliotheken häufig zum Einfügen und Abrufen von Objekten in verwendet HashMap. Die Methode wird auch verwendet, um sicherzustellen, dass nur eindeutige Objekte in anderen Implementierungen equalgespeichert werden , sowie in allen anderen Fällen, in denen Objekte verglichen werden müssen. Die Standardimplementierung der Methode in der Klasse vergleicht Verweise auf die Speicheradressen, die die Variablen speichern, und gibt nur dann zurück, wenn die Adressen übereinstimmen, d. h. die Variablen auf dasselbe Objekt verweisen. Java empfiehlt, die Methoden und zu überschreiben , wenn erwartet wird, dass der Vergleich der natürlichen Logik oder der Geschäftslogik folgt. Viele Klassen in den Standard-Java-Bibliotheken überschreiben sie, beispielsweise überschreibt die Klasse , sodass sie zurückkehrt, wenn die Inhalte der beiden verglichenen Objekte gleich sind. Die Wrapper-Klasse überschreibt die Methode , um einen numerischen Vergleich durchzuführen usw. Da Java auch auf die und- Methoden angewiesen ist, um ihre und zu vergleichen , bietet Java die folgenden Regeln zum Überschreiben dieser Methoden: HashSetSetequals()java.lang.Objecttrueequals()hashCode()StringequalstrueIntegerequalHashMapHashTableequals()hashCode()keyvalues
  1. Reflexivität: Das Objekt muss sich selbst gleich sein.
  2. Symmetrisch: Wenn a.equals(b)es zurückkehrt true, b.equals(a)muss es auch zurückkehren true.
  3. Transitivität: Wenn a.equals(b)es zurückkehrt trueund b.equals(c)auch zurückkehrt true, dann c.equals(a)muss es auch zurückkehren true.
  4. Konsistenz: Wiederholte Aufrufe einer Methode equals()müssen denselben Wert zurückgeben, solange einige der Eigenschaftswerte des Objekts nicht geändert werden. Das heißt, wenn in Java zwei Objekte gleich sind, bleiben sie gleich, solange ihre Eigenschaften unverändert bleiben.
  5. Vergleich null: Das Objekt muss überprüft werden null. Wenn das Objekt gleich ist null, sollte die Methode zurückgeben false, nicht NullPointerException. Beispielsweise a.equals(null)sollte es zurückgegeben werden false.

Vereinbarung zwischen equal und hashCode in Java

  1. Wenn die Objekte in den Ergebnissen der Methodenausführung gleich sind equals, müssen sie hashcodegleich sein.
  2. Wenn die Objekte in den Ergebnissen der Methodenausführung nicht gleich sind equals, können sie hashcodeentweder gleich oder unterschiedlich sein. Um die Leistung zu verbessern, ist es jedoch besser, unterschiedliche Objekte unterschiedliche Codes zurückgeben zu lassen.

So überschreiben Sie die Methode equal in Java

  1. @Override
    public boolean equals(Object obj) {
    /*1. Überprüfen*/if (obj == this) {
    /*und zurück */ return true;
             }
  2. Проверьте ein Objekt на null, а также проверьте, чтобы ein Objektы были одного типа. Не делайте проверку с помощью instanceof так Wie такая проверка будет возвращать true для подклассов и будет работать правильно только в случае если ваш класс объявлен Wie immutable. Вместо этого можно использовать getClass();

    if (obj == null || obj.getClass() != this.getClass()) {
                return false;
    }
  3. Объявите переменную типа, который вы сравниваете, и приведите obj к этому типу. Потом сравнивайте каждый атрибут типа начиная с численных атрибутов (если имеются) потому что численные атрибуты проверяются быстрей. Сравнивайте атрибуты с помощью операторов И и ИЛИ (так называемые short-circuit logical operators) для объединения проверок с другими атрибутами.

    Person guest = (Person) obj;
            return id == guest.id && (firstName == guest.firstName ||
                (firstName != null && firstName.equals(guest.getFirstName())))
                    && (lastName == guest.lastName || (lastName != null &&                      lastName .equals(guest.getLastName())));
    }
Полный пример переопределения метода equals в Java
/** * Person class with equals and hashcode implementation in Java * @author Javin Paul */
public class Person {
    private int id;
    private String firstName;
    private String lastName;

    public int getId() { return id; }
    public void setId(int 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; }
    @Override
    public boolean equals(Object obj) {
    if (obj == this) {
        return true;
    }
    if (obj == null || obj.getClass() != this.getClass()) {
        return false;
    }

    Person guest = (Person) obj;
    return id == guest.id
        && (firstName == guest.firstName
            || (firstName != null &&firstName.equals(guest.getFirstName())))        && (lastName == guest.lastName
            || (lastName != null && lastName .equals(guest.getLastName())
            ));
    }
    @Override
    public int hashCode() {
    final int prime = 31;
    int result = 1;
    result = prime * result + ((firstName == null) ? 0 : firstName.hashCode());             result = prime * result + id; result = prime * result +
        ((lastName == null) ? 0 : lastName.hashCode()); return result;
    }
 }

Распространенные ошибки при переопределении equals в Java

  1. Вместо того, чтобы переопределять метод equals (Override) программист перегружает его (Overload)Синтаксис метода equals() в классе Object определен Wie public boolean equals(Object obj), но многие программисты ненароком перегружают метод: public boolean equals(Person obj) - anstatt Object в качестве аргумента используют Name своего класса (напр. Person). Эту ошибку сложно обнаружить из-за static binding. Таким образом, если вы вызовете этот метод для ein Objektа своего класса, то метод не просто скомпoderруется, а даже сделает это корректно. Однако, если вы положите ваш ein Objekt в коллекцию, например ArrayList и вызовете метод contains(), работа которого основана на методе equals(), то метод contains не сможет обнаружить ваш ein Objekt.

  2. При переопределении метода equals() не проверять на null переменные, что в конечном итоге заканчивается NullPointerException при вызове equals(). Ниже представлен корректный Code.

    firstname == guest.firstname || (firstname != null &&
         firstname.equals(guest.firstname));
  3. Третья распространенная ошибка это не переопределять метод hashCode(), а только equals(). Вы обязаны переопределять оба метода equals() и hashCode() в Java. Метод hashCode используется в hash -коллекциях(например HashSet), и чем меньше будет коллизий (одинаковый Code при разных ein Objektах) тем эффективнее эти коллекции будут работать с ein Objektами вашего класса.

  4. Последняя распространенная ошибка программистов в том, что при переопределении метода equals() не сохраняется соответствие между методами equals() и compareTo(), что является неформальным требованием для избежания хранения дубликатов в Set (SortedSet, TreeSet).

Подсказки Wie писать в Java метод equals

  1. Большинство IDE такие Wie NetBeans, Eclipse и IntelliJ IDEA обеспечивают поддержку генерации методов equals() и hashCode(). В Eclipse нажмите правую кнопку -> source -> generate equals() и hashCode().

  2. Если в классе есть уникальный бизнес-ключ, то будет достаточно сделать проверку только на gleichtство этих полей. Как в нашем примере “id” - уникальный номер для каждого Person.

  3. При переопределении hashCode() в Java удостоверьтесь в использовании всех полей, что были использованы в методе equals().

  4. Stringund Wrapper-Klassen wie Integer, Floatund Doubleüberschreiben die Methode equals(), überschreiben sie jedoch StringBuffernicht.

  5. Erstellen Sie Felder nach Möglichkeit immutablemithilfe finalvon Variablen in Java.

  6. Verwenden Sie beim Vergleichen von StringObjekten equals()stattdessen den .-Operator ==.

  7. Zwei Objekte, die logisch gleich sind, aber von unterschiedlichen Objekten geladen werden, ClassLoaderkönnen nicht gleich sein. Denken Sie daran, dass die Überprüfung mit getClass()zu einem Ergebnis führt false, wenn die Loader-Klasse unterschiedlich ist.

  8. Verwenden Sie @Overridedie Annotation auch für die .-Methode hashCode, da dies subtile Fehler wie den Rückgabewert der int.-Methode verhindert. Einige Programmierer geben jedoch zurück long.

PS Liebe Kolleginnen und Kollegen! Ich fand diesen Artikel hilfreich bei der Lösung von Level-21-Problemen! Ich wünsche Ihnen viel Glück bei der Analyse dieses Themas, verwenden Sie die Übersetzung! Ich hoffe, dass Sie mir helfen, meine Bewertung zu verbessern, da ich jetzt nicht einmal mehr einen Kommentar in diesem Forum hinterlassen kann. Vielen Dank an alle! Ursprünglicher Artikel Ich habe einige Punkte aus Mangel an Freizeit weggelassen, aber ich habe alles übersetzt, was Sie wissen müssen, um Probleme der Stufe 21 zu lösen.
Kommentare
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION