JAVA

[Java] Equlas 와 hascode를 재정의하는 이유

포포015 2022. 5. 28. 11:54

목차

1. Equlas 란?

2. Hashcode 란?

3. 그래서 어떤상황에서 같이 재정의를 해야하는가?


1. Equals란 ?

객체는 기본적으로, 오버라이딩을 해서 재정의 하지않으면 Object의 equals의 메소드를 사용한다.

Object의 equals 내부를 보면 ==로 비교하는데 ==는 객체의 주소 값 자체를 비교하는것이다.


무엇이 나올것 같은가? 정답은 false가 나온다.
객체의 주소값은 당연히 new로 생성 했기 때문에 서로 다른게 정상이지만,
논리적으로 생각해보자. 위의 코드에선 홍길동이란 사람과 휴대전화번호가 두개가 같다.
그럼 현실 세계에선 두명의 사람일까? 휴대전화는 중복될수없는 고유정보인데?

우리는 논리적으로 같은 객체라고 판단하기위에 객체에 equals를 재정의해보자.

오버라이딩을 해서 재정의를 하면, 객체의 내부의 값을 비교한다. (논리적 동등성 충족 완료)

2. HashCode란?

객체 해시코드란, 객체를 식별하는 하나의 정수 값을 말한다.


객체에 오버라이딩을 해보자.

타고 타고 들어가보면, 오버라이딩한 내부 소스코드는 사진과 같이 구현되어 있다.
해당 객체에 대한 정확한 비교를 위해 hashcode를 재정의 하는건 알겠는데,
대체 31이라는 숫자는 왜 곱했을까?
- 이펙티브 자바라는 책을 보면, 31이라는 숫자는 소수이기때문에 선택한것이라고한다.
31이라는 숫자를 정한 정의도 요약하자면,
그냥 해시코드 충돌이 가장 적게 나는 숫자가 31이라서 31이라는 숫자를 선택한다고 한다.

3. 그래서 어떤상황에서 같이 재정의를 해야하는가?

위에서 설명한 내용을 생각해보면 동등성을 만족하기 위해선 equals만 재정의하면 된다.
물론 hashcode를 사용하지 않는 일반적인 상황에선, 문제가 없을수 있다.
하지만 아래와 같은 자료구조를 사용한다고 해봅시다.

위 이미지 같은경우 set의 구조를 사용했는데 (set은 기본적으로 중복된 값은 중복 등록되지않는다.)
일반적으로 생각하면 size의 숫자는 1이 나와야 할것 같지만,
객체에 equals만 재정의 했을경우, size는 2가 나온다.

이유는 add를 할때, 내부적으로 해시코드를 이용해 값을 비교하기 때문이다.


오버라이딩을 하지않으면 object의 hashcode를 사용하기때문에 논리적 동등성이 만족 하더라도 동일한 hashcode가 나오지않는다.


객체에 오버라이딩을 한다면, 논리적으로 동등성이 성립한다면 동일한 hashcode 정보가 나온다.
위에서 얘기한 예시처럼 홍길동과 휴대전화 동일하다면 동일인물이기 때문에,
논리적으로 동등하다. hashcode도 동일하게 나오는게 정상이다.


마지막으로 정리하자면 hashcode는 hash구조 자료구조에서 내부적으로 연산시 사용하기때문에,
정확한 비교를 위해서는 equals를 오버라이딩할땐 hashcode도 같이 재정의하는게 맞다.







'JAVA' 카테고리의 다른 글

[Java] Java 1.8을 왜 많이 쓸까?  (0) 2023.06.11
[Java] 자료구조 List, Set, Map의 차이  (1) 2021.05.31
java 명명 표기법  (0) 2021.02.26