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를 리턴합니다.
객체 자체를 비교하려면 이 메소드를 사용하는 것이 좋습니다.
참고
Related Posts
- Java - Unsupported class file major version 61 에러
- Java - String.matches()로 문자열 패턴 확인 및 다양한 예제 소개
- Java - 문자열 공백제거 (trim, replace)
- Java - replace()와 replaceAll()의 차이점
- Java - ArrayList 초기화, 4가지 방법
- Java - 배열 정렬(Sorting) (오름차순, 내림차순)
- Java - 문자열(String)을 비교하는 방법 (==, equals, compare)
- Java - StringBuilder 사용 방법, 예제
- Java - 로그 출력, 파일 저장 방법 (Logger 라이브러리)
- Java IllegalArgumentException 의미, 발생 이유
- Java - NullPointerException 원인, 해결 방법
- Seleninum의 ConnectionFailedException: Unable to establish websocket connection 해결
- Java - compareTo(), 객체 크기 비교
- Java - BufferedWriter로 파일 쓰기
- Java - BufferedReader로 파일 읽기
- Java charAt() 함수 알아보기
- Java - BigInteger 범위, 비교, 연산, 형변환
- Java contains()로 문자(대소문자 X) 포함 확인
- Java - Set(HashSet)를 배열로 변환
- Java - 문자열 첫번째 문자, 마지막 문자 확인
- Java - 문자열 한글자씩 자르기
- Java - 문자열 단어 개수 가져오기
- Java - 1초마다 반복 실행
- Java - 배열을 Set(HashSet)로 변환
- Java - 여러 Set(HashSet) 합치기
- Java - 명령행 인자 입력 받기
- Java - 리스트 역순으로 순회, 3가지 방법
- Java - 특정 조건으로 리스트 필터링, 3가지 방법
- Java - HashMap 모든 요소들의 합계, 평균 계산
- Java - 특정 조건으로 HashMap 필터링
- Java - 싱글톤(Singleton) 패턴 구현
- Java - 숫자 왼쪽에 0으로 채우기
- Java - String 배열 초기화 방법
- Java - 정렬된 순서로 Map(HashMap) 순회
- Java - HashMap에서 key, value 가져오기