우주먼지
Published 2023. 3. 15. 19:03
HashCode Data Architect/Data Structure

💡 hashCode

객체의 주소값을 변환하여 생성된 객체의 고유한 정수값이다.

두 객체가 동일한 객체인지 동일성을 체크할 때 사용한다.

 

특징

  • 해시 함수에 중요한것은 데이터의 속성이다.
  • 연산이 빨라야 한다.
  • 최대한 코드 충돌을 지양해야한다.
  • 코드를 재실행 했을떄 같은 객체라도 다른 값이 나올 수 있다.
    • Object의 hashCode()를 Override 해야한다.
    • Object 클래스의 hashCode는 메모리 위치를 기반으로 실행된다.
    • 재실행마다 객체는 다른 위치에 저장되기 때문에 다른값이 반환된다.
  • 같은 실행 환경일 경우 두 요소가 같다면 항상 같은 값을 반환해야 한다. (equals)
    • 객체의 경우 힙에서의 위치, 문자열의 경우는 문자열 비교 등

예시

아래 예시의 person1과 person2의 hashCode는 당연히 다르다.

hashCode는 주소값을 기반으로 생성된 정수 값이기 때문에 2,3의 hashCode는 동일하다.

public class HashCode {
    public static void main(String[] args) {
        Person person1 = new Person("Kim");
        Person person2 = new Person(new String("Kim"));
        Person person3 = person2;

        System.out.println(person1.hashCode());
        System.out.println(person2.hashCode());
        System.out.println(person3.hashCode());
    }
}

class Person {
    String name;

    public Person(String name) {
        this.name = name;
    }

    @Override
    public boolean equals(Object obj) {
        Person anotherObj = (Person) obj;
        return (this.name.equals(anotherObj.name));
    }
}

// 결과값
// 3565735997
// 1735600054
// 1735600054

💡 String 클래스의 hashCode()

String은 재정의한 equals()에서 각 문자열에서 한 글자씩 비교하는 방식이다.

아래 코드는 문자열에서 한글자씩 가져와서 정수값으로 변경하고 정수와 더하면
해당 글자의 아스키 코드의 값을 사용한다.

 

31을 곱하는 이유는 홀수이기 때문이다.

짝수를 곱했을 때 오버플로우 되면 정보 손실이 발생할 수 있기 때문이다.

이진수에서 2를 곱하면 비트가 왼쪽으로 1칸씩 이동한다.

 

홀수 중 31의 장점은 31 * i가 (i << 5) - i 와 같기 때문에 곱셈 대신 비트 이동 및 뺄셈으로 처리하여
성능상 이점이 있기 떄문이며, 요즘은 VM에서 자동으로 최적화를 해준다.

 

결론적으로 주소값을 기준으로 정수값의 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;
}

 

'Data Architect > Data Structure' 카테고리의 다른 글

Hash Chaining & loadFactor  (0) 2023.02.26
Resolve Hash Collision  (0) 2023.02.26
Hash 충돌 & 양수 변환 & loadFactor  (0) 2023.02.26
해시 (Hash)  (0) 2023.02.12
스택 & 큐 (Stack & Queue)  (0) 2023.02.12
profile

우주먼지

@o귤o

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!

검색 태그