<aside>
💡 *equals
를 재정의한 클래스 모두에서 hashCode
도 재정의해야 한다!*
</aside>
hashCode
일반 규약을 어기게 되어, 해당 클래스의 인스턴스를 HashMap
이나 HashSet
같은 컬렉션의 원소로 사용할 때 문제를 일으킨다.
Object
명세에서hashCode
관련된 규약들
*equals
비교에 사용되는 정보가 변경되지 않았다면, 애플리케이션이 실행되는 동안 그 객체의 hashCode
는 항상 같은 값을 반환해야 한다.*
*equals
가 두 객체를 같다고 판단했다면, 두 객체의 hashCode
는 똑같은 값을 반환해야 한다.**equals
가 두 객체를 다르다고 판단했더라도, 두 객체의 hashCode
가 서로 다른 값을 반환할 필요는 없다.*
hashCode
재정의를 잘못했을 때 크게 문제가 되는 조항은 두 번째다.
즉, 논리적으로 같은 객체는 같은 해시코드를 반환해야 한다.
equals
는 물리적으로 다른 두 객체를 논리적으로 같다고 하지만, 기본 hashCode
는 이 둘이 다르다고 판단한다.예시
m.get(new PhoneNumber(707, 867, 5309))
를 실행하면 "제니"
가 아닌 null
을 반환한다.HashMap
에 넣을 때, 꺼낼 때 서로 다른 인스턴스를 사용하고 hashCode
를 재정의하지 않았기 때문에 서로 다른 해시코드를 반환한다.Map<PhoneNumber, String> m = new HashMap<>();
m.put(new PhoneNumber(707, 867, 5309), "제니");
hashCode
를 재정의해주면 해결된다!
@Override
public int hashCode() {
return 42;
}
O(1)
인 해시테이블이 O(n)
으로 느려져서 객체가 많아지면 사용할 수 없게 된다.<aside>
💡 그렇다면, 서로 다른 인스턴스에 다른 해시코드를 반환하는 좋은 hashCode
함수를 작성하는 방법은?
</aside>