equals()를 재정의하는데, 왜 hashCode()도 재정의하라는 걸까?

KIMA·2024년 1월 2일
1

java

목록 보기
9/10

두 객체가 같은 내용을 가지는지 확인 하기 위해서는, equals()를 다음의 로직으로 재정의한다.
1. 두 객체의 참조값을 비교한다.
2. 다르다면? 두 객체가 같은 클래스인지 비교한다.
3. 다르다면? 두 객체가 가진 멤버 변수 값이 각각 모두 같은지 비교한다.

이렇게 재정의를 마치면, 다음의 경고를 볼 수 있다.

hashCode()도 재정의하라는 걸까?

그 이유는 equals()가 true로 나오는 두 객체는 hashCode()도 반드시 같아야하기 때문이다.
hash 값을 사용하는 Collection(HashSet, HashMap, HashTable)은 다음의 과정으로 두 객체가 같은지 판단한다.
1. hashCode() 비교
2. 같으면? equals() 비교
따라서 equals()가 두 객체의 주소가 아닌 내용을 비교하도록 재정의하였다면, 기본적으로 객체의 주소값으로 해시코드를 생성하는 hashCode()도 반드시 이와 같은 규칙을 따르도록 재정의해줘야한다.

💡 equals() 이전에 hashCode()로 먼저 비교하는 이유
equals() 내부에서 두 객체가 가진 멤버 변수 값이 각각 모두 같은지 비교하는 과정이 많은 비용을 야기시킨다.
예를들어, A클래스 타입의 두 객체를 비교하려고 하는데 A클래스가 멤버 변수로 B클래스를 가지고 있다면? B클래스 또한 멤버 변수로 C클래스를 가지고 있다면? 두 객체 비교하기위해 굉장히 많은 연산을 수행해야하는 복잡한 상황이 연출된다.
따라서, 두 객체 비교시 hashCode()의 리턴 값 즉, 각자의 멤버 변수들을 연산하여 생성한 해시코드를 비교하여 다르면 먼저 걸러주는 것이 더 효율적이다.

예를 들어 hashCode()를 재정의할 때, 매개변수로 주어진 값들을 이용해서 고유한 해시코드를 생성하는 Objects.hash()에 클래스의 멤버 변수들을 인자로 전달하여 리턴받은 해시코드를 반환하도록 정의한다.

Reference

profile
안녕하세요.

0개의 댓글