자바에서 equals()와 hashCode()를 오버라이딩할 때 어떤 것들을 고려해야 할까요?


equals()hashCode()를 오버라이딩할 때 어떤 것들을 고려해야 할까요?

  • 2016년 05월 14일에 작성됨

조회수 73


1 답변


좋아요
0
싫어요
채택취소하기

이론적으로:

eauqls()(javadoc)는 동등관계를 정의합니다. 그리고 그 결과는 항상 동일해야 합니다. (만약 객체의 데이터가 수정되더라도, 항상 동일한 값을 반환할 수 있어야 합니다.) 게다가, o.equals(null)은 항상 false를 반환해야 합니다.

hashCode() (javadoc)도 항상 일관성을 유지해야 합니다. (equals()관점에서 객체가 수정되지 않는다면, hashCode()는 항상 동일한 값을 반환해야 합니다.)

두 메소드들 간의 관계는 다음 조건을 항상 충족시켜야 합니다.

a.equals(b)일 때, a.hashCode()와 b.hashCode()는 반드시 같아야 합니다.

구현시:

만약에 둘 중 하나라도 오버라이딩을 하고자 한다면, 반드시 둘 다 오버라이딩을 해야 합니다.

equals()와 hashCode()를 계산하기 위한 동일한 필드 셋을 사용하세요.

Apache Commons Lang 라이브러리의 EqualsBuilderHashCodeBuilder와 같은 좋은 헬퍼 클래스들을 사용해도 좋습니다. 다음은 그 예입니다.

public class Person {
    private String name;
    private int age;
    // ...

    @Override
    public int hashCode() {
        return new HashCodeBuilder(17, 31). // two randomly chosen prime numbers
            // if deriving: appendSuper(super.hashCode()).
            append(name).
            append(age).
            toHashCode();
    }

    @Override
    public boolean equals(Object obj) {
       if (!(obj instanceof Person))
            return false;
        if (obj == this)
            return true;

        Person rhs = (Person) obj;
        return new EqualsBuilder().
            // if deriving: appendSuper(super.equals(obj)).
            append(name, rhs.name).
            append(age, rhs.age).
            isEquals();
    }
}

추가적으로 기억하기:

HashSet, LinkedHashSet, HashMap, Hashtable 혹은 WeakHashMap과 같은 해쉬 기반의 collection 또는 map을 사용할 때는 collection에 객체가 존재하는 시점에서 collection에 삽입하는 키 객체의 hashCode()는 절대 변경하면 안됩니다. 이것을 보장하는 가장 좋은 방법은 변하지 않는 키를 만드는 것입니다. 그럼으로 인해서 추가적인 이점도 얻을 수 있습니다.

  • 2016년 05월 15일에 작성됨

로그인이 필요한 기능입니다.

Hashcode는 개발자들을 위한 무료 QnA사이트 입니다. 작성한 답변에 다른 개발자들이 댓글을 작성하거나 좋아요/싫어요를 할 수 있기 때문에 계정을 필요로 합니다.
► 로그인
► 계정만들기
Close