JavaRush /Java Blog /Random-KO /Java에서 equals() 및 hashCode() 메소드 오버로드
Coder
레벨 17

Java에서 equals() 및 hashCode() 메소드 오버로드

Random-KO 그룹에 게시되었습니다

Java에서 equals() 및 hashCode() 메서드 재정의

EqualshashCode클래스에 선언되고 Object표준 Java 라이브러리에 포함된 기본 메서드 입니다 . Java에서 equals() 및 hashCode() 메소드 오버로드 - 1이 방법은 еquals()객체를 비교하고 hashCode객체에 대한 정수 코드를 생성하는 데 사용됩니다. 이러한 메소드는 NET에서 객체를 삽입하고 검색할 때 Java 표준 라이브러리에서 널리 사용됩니다 HashMap. 이 메서드는 또한 개체를 비교해야 하는 다른 경우뿐만 아니라 다른 구현 에서는 equal고유한 개체만 저장되도록 하는 데에도 사용됩니다 . 클래스에 있는 메서드의 기본 구현은 변수가 저장하는 메모리 주소에 대한 참조를 비교하고 주소가 일치하는 경우에만 반환합니다. 즉, 변수는 동일한 개체를 참조합니다. Java에서는 자연스러운 논리나 비즈니스 논리에 따라 비교가 수행되기를 기대하는 경우 및 메서드를 재정의할 것을 권장합니다. 표준 Java 라이브러리의 많은 클래스는 이를 재정의합니다. 예를 들어 클래스는 비교되는 두 개체의 내용이 동일한 경우 반환되도록 재정의합니다 . 래퍼 클래스는 수치 비교 등을 수행하는 메서드를 재정의합니다. Java는 및 메소드 를 사용하여 과 를 비교 하므로 Java는 이러한 메소드를 대체하기 위해 다음 규칙을 제공합니다. HashSetSetequals()java.lang.Objecttrueequals()hashCode()StringequalstrueIntegerequalHashMapHashTableequals()hashCode()keyvalues
  1. 재귀성: 객체는 자신과 동일해야 합니다.
  2. 대칭: a.equals(b)을 반환 하면 trueb.equals(a)반환해야 합니다 true.
  3. 전이성: a.equals(b)반환 true하고 b.equals(c)또한 반환하는 true경우 c.equals(a)또한 반환해야 합니다 true.
  4. 일관성: 메소드에 대한 반복 호출은 equals()객체의 속성 값 중 일부가 변경되지 않는 한 동일한 값을 반환해야 합니다. 즉, Java에서 두 객체가 동일하면 해당 속성이 변경되지 않는 한 동일합니다.
  5. 비교 null: 개체를 확인해야 합니다 null. 개체가 와 같으면 null메서드는 false가 아닌 을 반환해야 합니다 NullPointerException. 예를 들어, a.equals(null)를 반환해야 합니다 false.

Java의 equals와 hashCode 간의 일치

  1. 메소드 실행 결과에서 객체가 동일하면 동일해야 합니다 equals.hashcode
  2. 메소드 실행 결과에서 객체가 동일하지 않으면 동일하거나 다를 수 있습니다 equals. hashcode그러나 성능을 향상시키려면 서로 다른 개체가 서로 다른 코드를 반환하도록 하는 것이 좋습니다.

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. String및 와 같은 래퍼 클래스는 Integer메서드 를 재정의 Float하지만 재정의 하지는 않습니다.Doubleequals()StringBuffer

  5. 가능하다면 Java에서 변수를 immutable사용하여 필드를 만드세요 final.

  6. String객체를 비교할 때는 equals()대신 .연산자를 사용하세요 ==.

  7. 논리적으로 동일하지만 다른 객체에서 로드된 두 객체는 ClassLoader​​동일할 수 없습니다. 로더 클래스가 다른 경우 로 확인하면 결과 getClass()가 반환된다는 점을 기억하세요.false

  8. @Override.메서드에도 주석을 사용하면 hashCode의 반환 값과 같은 미묘한 오류를 방지할 수 int있지만 일부 프로그래머는 를 반환합니다 long.

PS 동료 여러분! 이 기사가 레벨 21 문제를 해결하는 데 유용하다고 생각합니다! 이 주제를 분석하는 데 행운이 있기를 바랍니다. 번역을 사용하세요! 이제 나는 이 포럼에 댓글을 남길 수도 없기 때문에 내 평가를 높이는 데 도움이 되기를 바랍니다. 정말 고마워요, 여러분! 원글 시간이 부족하여 일부 내용을 생략했지만, 레벨 21 문제를 해결하기 위해 알아야 할 모든 내용을 번역했습니다.
코멘트
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION