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

조회수 2189회

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

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()는 절대 변경하면 안됩니다. 이것을 보장하는 가장 좋은 방법은 변하지 않는 키를 만드는 것입니다. 그럼으로 인해서 추가적인 이점도 얻을 수 있습니다.

답변을 하려면 로그인이 필요합니다.

프로그래머스 커뮤니티는 개발자들을 위한 Q&A 서비스입니다. 로그인해야 답변을 작성하실 수 있습니다.

(ಠ_ಠ)
(ಠ‿ಠ)