Java의 HashSet을 공부하던 중 hashCode에 대해 의문점이 있습니다.
HashSet - hashcode()의 오버라이딩 조건
1) 동일 객체에 대해 hashCode()를 여러 번 호출해도 같은 값을 반환해야 한다.
2) equals()로 비교해서 true를 얻은 두 객체의 hashCode()값은 일치해야 한다.
* false일 때도 두 객체의 hashCode()의 값이 같을 수도 있다.
원래 객체의 값에 의해 나온 hashCode의 값이 일치해야 하는 점은 이해합니다만,
equals로 비교했을 때 false가 나온 경우에도 hashCode()의 값이 같을 수도 있다고 써있더라구요.
그 이유가 무엇인가요? 그리고 그렇게 됐을 때, hashCode를 이용해서 비교할 수는 없지 않나요?
equals로 비교했을 때 false가 나온 경우에도 hashCode()의 값이 같을 수 도 있는 이유?
equals(Object o) 메서드는 객체간 비교를 하는 메서드입니다.
만약 false가 나왔다면 서로 다른 객체로 볼 수 있습니다.
hashCode()의 값은 Hash 메서드의 결과 값입니다.
아래와 같이 객체의 상태 값들을 이용해서 hashCode() 값을 얻어 올 수 있습니다.
/* String.java#hashCode() */ /** * Returns a hash code for this string. The hash code for a * {@code String} object is computed as * <blockquote><pre> * s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1] * </pre></blockquote> * using {@code int} arithmetic, where {@code s[i]} is the * <i>i</i>th character of the string, {@code n} is the length of * the string, and {@code ^} indicates exponentiation. * (The hash value of the empty string is zero.) * * @return a hash code value for this object. */ public int hashCode() { int h = hash; final int len = length(); if (h == 0 && len > 0) { for (int i = 0; i < len; i++) { h = 31 * h + charAt(i); } hash = h; } return h; }서로 다른 타입의 객체(equals(otherTypeObject) == false)간 hashCode()의 값을 일치할 수 도 있습니다.
서로 다른 타입의 객체(equals(otherTypeObject) == false)간 Hash 메서드가 다를 수 있는데, 우연히도 그 결과가 일치할 수 있습니다.
그렇게 됐을 때, hashCode를 이용해서 비교할 수는 없지 않나요?
앞선 설명대로 서로 다른 타입의 객체(equals(otherTypeObject) == false)간 hashCode를 이용한 비교는 같은 값이 나올 수 있기 때문에 할 수 없습니다.
하지만 같은 타입의 객체(equals(sameTypeObject) == true)간 hashCode()를 이용한 비교는 가능 합니다.
equals로 비교했을 때 false가 나온 경우에도 hashCode()의 값이 같을 수도 있는 이유에 대해서 질문하셨습니다.
비둘기집 원리를 아시나요...?
자바에서 만들 수 있는 객체의 개수는 무한합니다. 그리고 모든 객체는 해시코드를 하나씩 가집니다.
하지만 (hashcode가 int이기 때문에) 해시코드가 가능한 경우는 43억개도 되지 않습니다.
객체 43억개가 모두 해시코드가 다르다면... 있을 수 없는 일이겠죠?