Java hashCode랑 identityHashCode의 차이점이 무엇일까요? 그에 대해서 답을 하기 전에, 간단한 실험을 하고 넘어갑시다. identityHashCode는 객체가 다르면, 무조건 다른 값을 리턴할까요? 즉, 이 메서드의 리턴 값이, 객체의 고윳값이 될 수 있을까요? 사실 저는 그런 줄 알았습니다.

 

 

 100만개짜리 Object 객체 배열을 만들었습니다. 그리고, 100만개의 Object 객체를 만들었습니다. 그리고, 객체 arr[i]의 identityHashCode 값을 treeset에다가 넣었습니다. 만약에, 객체 각각의 identityHashCode가 고유하다면, treeset에 들어간 원소 갯수는 100만개였을 겁니다.

 

 

 그런데 실제로는 999768개입니다. TreeSet은 기본적으로, 중복을 허용하지 않는 Collection입니다. 예를 들어서, 3, 2, 7, 6, 7이 순서대로 트리셋에 add되었다고 가정해 봅시다.

 

 

 3, 2, 7이 추가된 후에 트리 모습은 다음과 같을 겁니다. 6은 트리 내에 없습니다.

 

 

 따라서, 6을 add 하라는 Query가 수행된 후에는, 트리 모양이 이렇게 될 겁니다. 문제는, 그 다음에 7을 추가하라는 명령이 들어왔습니다. 그런데 보니까 7이라는 원소는 있습니다.

 

 

 

 따라서, 7은 추가되지 않습니다. 추가하라는 명령은 5번 들어왔는데 treeset의 사이즈는 4입니다. 중복된 원소가 있었기 때문에, add Query의 갯수와 실제 tree에 들어간 원소의 갯수가 차이가 난 셈입니다. 100만개를 넣었는데, 그 중 999768개만 들어있다는 것은, 중복이 있었다는 소리입니다. 즉, 같은 객체라면 identity 메서드를 호출하면 동일한 값이 나오는 건 맞습니다. 그렇지만, 다른 객체라도 동일한 값이 나올 여지는 있다는 겁니다. 또한, 이 메서드는 int를 리턴합니다. 객체의 주솟값을 리턴하지는 않아요.

 

 여기서 중요한 사실은 이 함수의 값이 같다고 해서, 객체가 동일하지는 않다는 겁니다.

 

 


 그러면, hashCode랑, identityHashCode는 어떤 차이가 있을까요? arr[i]는 Object 객체입니다. 저는 arr에 저장되어 있는 Object 객체 100개에 대해서 hashCode의 값과, System.identity(Object)의 값을 출력해 보았습니다.

 

 

 우연히도, 모두 같았습니다. 정확히 100개를 찍었는데, 그게 우연히 모두 같을 확률이 얼마나 될까요? 즉, hashCode를 오버라이딩 하지 않았다면, obj.hashCode() 값이랑 System.identityHashCode(obj)의 값은 같습니다.

 

 


 그런데, hashCode가 오버라이딩이 되어 있다면 어떨까요? String 클래스는 hashCode가 오버라이딩 되어 있어요.

 

 

 객체 2개를 생성했습니다.

 

 

  이 둘은 별개의 Object이기 때문에, identity의 값은 같다는 보장이 없습니다.

 

 

 실제로 출력 결과를 보면, 366712642, 1829164700으로 다르다는 것을 알 수 있습니다. 그런데 a와 b의 hashCode를 찍은 값은 97로 같다는 것을 알 수 있어요. 둘이 별개의 객체인데도요. 이는 String 클래스에서 문제의 메서드를 재정의를 했기 때문입니다. 어떻게 재정의를 했는지 간단하게 봅시다.

 

 

 대충 보니까 31진법 비슷하게 처리하고 있어요. 어찌 되었던 두 String의 내용이 같으면 h값은 같게 나올 수 밖에 없어요. 물론 이 둘의 내용이 다르다고, h값이 항상 다르다는 보장은 없어요. 같을 수도 있을 거에요. 하지만, a와 b의 내용이 같으면 같은 값이 나온다는 것을 알 수 있어요.

 

 정리를 해 봅시다. identityHashCode에 비해서, hashCode는 내가 오버라이딩을 할 수 있어요. 그렇지만 identity는 오버라이딩을 할 수 없어요. 즉, 재정의를 하지 못합니다. 약에 오버라이딩이 되지 않았다면, identity랑 해쉬코드 메서드의 리턴 값이 같다. 그게 아니라면 다를 수도 있다는 점만 챙겨도 무난할 듯 싶네요.