JavaRush /Java Blog /Random EN /Overloading equals() and hashCode() methods in Java
Coder
Level 17

Overloading equals() and hashCode() methods in Java

Published in the Random EN group

Overriding equals() and hashCode() methods in Java

Equalsand hashCodeare the fundamental methods declared in the class Objectand contained in the standard Java libraries. Overloading equals() and hashCode() methods in Java - 1The method еquals()is used to compare objects and hashCodeto generate an integer code for the object. These methods are widely used in the Java standard libraries when inserting and retrieving objects in HashMap. The method equalis also used to ensure that only unique objects are stored in HashSetother Setimplementations, as well as in any other cases where objects need to be compared. The default implementation of the method equals()in the class java.lang.Objectcompares references to the memory addresses that the variables store and returns trueonly if the addresses match, in other words, the variables refer to the same object. Java recommends overriding the equals()and methods hashCode()if you expect the comparison to be done according to natural logic or business logic. Many classes in the standard Java libraries override them, for example the class Stringoverrides equalsso that it returns trueif the contents of the two objects being compared are the same. The wrapper class overrides Integerthe method equalto perform a numerical comparison, and so on. Since Java HashMapalso relies on and methods to compare their and , Java offers the following rules for overriding these methods: HashTableequals()hashCode()keyvalues
  1. Reflexivity: The object must be equal to itself.
  2. Symmetrical: if a.equals(b)it returns true, then b.equals(a)it must also return true.
  3. Transitivity: if a.equals(b)it returns trueand b.equals(c)also returns true, then c.equals(a)it must also return true.
  4. Consistency: Repeated calls to a method equals()must return the same value as long as some of the object's property values ​​are not changed. That is, if two objects are equal in Java, then they will be equal as long as their properties remain unchanged.
  5. Comparison null: The object must be checked for null. If the object is equal to null, then the method should return false, not NullPointerException. For example, a.equals(null)it should return false.

Agreement between equals and hashCode in Java

  1. If the objects are equal in the results of method execution equals, then they hashcodemust be the same.
  2. If the objects are not equal in the results of method execution equals, then they hashcodecan be either the same or different. However, to improve performance, it is better to have different objects return different codes.

How to override equals method in Java

  1. @Override
    public boolean equals(Object obj) {
    /*1. Check*/if (obj == this) {
    /*and return */ return true;
             }
  2. Проверьте an object на null, а также проверьте, чтобы an objectы были одного типа. Не делайте проверку с помощью instanceof так How такая проверка будет возвращать true для подклассов и будет работать правильно только в случае если ваш класс объявлен How 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 определен How public boolean equals(Object obj), но многие программисты ненароком перегружают метод: public boolean equals(Person obj) - instead of Object в качестве аргумента используют Name своего класса (напр. Person). Эту ошибку сложно обнаружить из-за static binding. Таким образом, если вы вызовете этот метод для an object своего класса, то метод не просто скомпorруется, а даже сделает это корректно. Однако, если вы положите ваш an object в коллекцию, например ArrayList и вызовете метод contains(), работа которого основана на методе equals(), то метод contains не сможет обнаружить ваш an object.

  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 при разных an objectх) тем эффективнее эти коллекции будут работать с an objectми вашего класса.

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

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

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

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

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

  4. Stringand wrapper classes such as Integer, Floatand Doubleoverride the method equals(), but StringBufferdoes not override.

  5. Whenever possible, make fields immutableusing finalvariables in Java.

  6. When comparing Stringobjects, use equals()the . operator instead ==.

  7. Two objects that are logically equal but loaded from different objects ClassLoadercannot be equal. Remember that checking with getClass()will return falseif the loader class is different.

  8. Use @Overridethe annotation also on the . method hashCode, as this prevents subtle errors such as the return value of the int. However, some programmers return long.

PS Dear colleagues! I found this article useful in solving level 21 problems! I wish you good luck in analyzing this topic, use the translation! I hope that you will help me raise my rating, since now I can't even leave a comment on this forum. Thanks a lot, everyone! Original article I omitted some points due to lack of free time, but I translated everything you need to know to solve level 21 problems.
Comments
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION