자바에서 equals()와 hashCode()를 오버라이딩할 때 어떤 것들을 고려해야 할까요?
조회수 2194회
1 답변
-
이론적으로:
eauqls()
(javadoc)는 동등관계를 정의합니다. 그리고 그 결과는 항상 동일해야 합니다. (만약 객체의 데이터가 수정되더라도, 항상 동일한 값을 반환할 수 있어야 합니다.) 게다가,o.equals(null)
은 항상 false를 반환해야 합니다.hashCode()
(javadoc)도 항상 일관성을 유지해야 합니다. (equals()
관점에서 객체가 수정되지 않는다면,hashCode()
는 항상 동일한 값을 반환해야 합니다.)두 메소드들 간의 관계는 다음 조건을 항상 충족시켜야 합니다.
a.equals(b)
일 때, a.hashCode()와 b.hashCode()는 반드시 같아야 합니다.구현시:
만약에 둘 중 하나라도 오버라이딩을 하고자 한다면, 반드시 둘 다 오버라이딩을 해야 합니다.
equals()와 hashCode()를 계산하기 위한 동일한 필드 셋을 사용하세요.
Apache Commons Lang 라이브러리의 EqualsBuilder와 HashCodeBuilder와 같은 좋은 헬퍼 클래스들을 사용해도 좋습니다. 다음은 그 예입니다.
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()는 절대 변경하면 안됩니다. 이것을 보장하는 가장 좋은 방법은 변하지 않는 키를 만드는 것입니다. 그럼으로 인해서 추가적인 이점도 얻을 수 있습니다.
댓글 입력