Java - System.identityHashCode()와 hashCode()의 차이점

JS · 30 Jun 2020

System.identityHashCode()hashCode()는 모두 객체의 고유한 값을 리턴한다는 점에서 같습니다. 하지만 차이점이 있습니다.

System.identityHashCode()

System.identityHashCode()는 객체의 고유한 hashcode를 리턴하는 메소드입니다.

인자로 전달된 객체에 대한 hashcode가 int로 리턴됩니다.

public static native int identityHashCode(Object x)

다음과 같이 사용할 수 있습니다. 아래 예제에서 str1과 str2는 동일한 객체를 가리키기 때문에 hashcode가 동일합니다. 하지만 str3는 다른 객체이기 때문에 hashcode가 다릅니다.

String str1 = "Hello";
String str2 = "Hello";
String str3 = new String("Hello");

System.out.println("str1 hashCode ? " + System.identityHashCode(str1));
System.out.println("str2 hashCode ? " + System.identityHashCode(str2));
System.out.println("str3 hashCode ? " + System.identityHashCode(str3));

Output:

str1 hashCode ? 1789447862
str2 hashCode ? 1789447862
str3 hashCode ? 38997010

아래와 같이 다른 객체와도 비교할 수 있습니다.

File file1 = new File("Hello");
String str2 = "Hello";

System.out.println("file1 hashCode ? " + System.identityHashCode(file1));
System.out.println("str2 hashCode ? " + System.identityHashCode(str2));

Output:

file1 hashCode ? 1789447862
str2 hashCode ? 38997010

System.identityHashCode(null)와 같이 null에 대한 리턴 값은 0입니다.

hashCode()

hashCode()는 모든 객체의 부모 클래스인 Object 클래스에 정의되어있습니다.

public native int hashCode();

그리고 하위 클래스들은 hashCode()를 오버라이드할 수 있습니다.

그렇기 때문에 다음과 같이 서로 다른 객체이지만 hashcode가 동일한 경우가 있습니다.

String str1 = "Hello";
String str2 = "Hello";
String str3 = new String("Hello");

System.out.println("str1 hashCode ? " + str1.hashCode());
System.out.println("str2 hashCode ? " + str2.hashCode());
System.out.println("str3 hashCode ? " + str3.hashCode());

Output:

str1 hashCode ? 69609650
str2 hashCode ? 69609650
str3 hashCode ? 69609650

str1과 str2는 같은 object이기 때문에 hashcode가 같을 수 있습니다. 하지만 str2와 str3는 다른 객체이기 때문에 hashcode가 다를 것으로 예상했지만 같습니다.

그 이유는 String 클래스에서 hashCode()를 다음과 같이 오버라이드하였기 때문입니다.

public int hashCode() {
    int h = hash;
    if (h == 0 && value.length > 0) {
        char val[] = value;

        for (int i = 0; i < value.length; i++) {
            h = 31 * h + val[i];
        }
        hash = h;
    }
    return h;
}

코드를 보시면 String의 문자열인 value로 hashcode를 만들고 있습니다. 그래서 object는 달라도 문자열이 같으면 동일한 hashcode를 리턴하게 됩니다.

정리

Object의 hashCode() 메소드는 하위 클래스에서 override가 가능하기 때문에 객체마다 유일한 값을 갖고 있지 않습니다. 객체의 특성이 동일하다는 것을 표현하기 위해 이 메소드를 오버라이드할 수 있습니다. 예를 들어, String의 hashcode가 갖다면 객체는 달라도 문자열은 동일하다는 것을 의미합니다.

반면에 System.identityHashCode()는 오버라이드가 안되며 객체의 고유한 hashCode를 리턴합니다. 객체 자체를 비교하려면 이 메소드를 사용하는 것이 좋습니다.

참고

댓글을 보거나 쓰려면 이 버튼을 눌러주세요.
codechachaCopyright ©2019 codechacha