본문 바로가기
Java

equals와 hash code

by 내 멋대로 삶 2022. 1. 22.
// Object의 기본 equals 메서드

public boolean equals(Object obj)
{
return
(this== obj); }
  • 동일성 비교는 == 비교다. 객체 인스턴스의 주소 값을 비교한다.
  • 동등성 비교는 equals() 메소드를 사용해서 객체 내부의 값을 비교한다.

 

Java hash code란

객체 해시코드란 객체를 식별하는 하나의 정수값을 말한다. Object의 hashCode() 메소드는 객체의 메모리 번지를 이용해서 해시코드를 만들어 리턴하기 때문에 객체 마다 다른 값을 가지고 있다.

우선 hashCode() 메소드를 실행해서 리턴된 해시코드 값이 같은지를 본다. 해시 코드값이 같으면 equals() 메소드로 다시 비교한다. 이 두개가 모두 맞아야 동등 객체로 판단한다. 

Java HashTable

equals와 hashcode 메서드를 이해하기 위해서 자바에서 HashTable이 작동하는 원리를 간단히 살펴보자.

(참고로 HashTable 뿐만 아니라 HashMap, HashSet 모두 아래의 동작 원리를 동일하다.)

 

HashTable은 <key,value> 형태로 데이터를 저장한다. 이 때 해시 함수(Hash Function)을 이용하여 key값을 기준으로 고유한 식별값인 해시값을 만든다. (hashcode가 해시값을 만드는 역할을 한다.) 이 해시값을 버킷(Bucket)에 저장한다.

하지만 HashTable 크기는 한정적이기 때문에 같은 서로 다른 객체라 하더라도 같은 해시값을 갖게 될 수도 있다.

 

equals()와 hashcode()를 같이 재정의해야 하는 이유

만약 equals()와 hashcode() 중 하나만 재정의 하면 어떻게 될까? 위 예에서도 봤듯이 hashcode()를 재정의 하지 않으면 같은 값 객체라도 해시값이 다를 수 있다. 따라서 HashTable에서 해당 객체가 저장된 버킷을 찾을 수 없다.

반대로 equals()를 재정의하지 않으면 hashcode()가 만든 해시값을 이용해 객체가 저장된 버킷을 찾을 수는 있지만 해당 객체가 자신과 같은 객체인지 값을 비교할 수 없기 때문에 null을 리턴하게 된다. 따라서 역시 원하는 객체를 찾을 수 없다.

이러한 이유로 객체의 정확한 동등 비교를 위해서는 (특히 Hash 관련 컬렉션 프레임워크를 사용할때!) Object의 equals() 메소드만 재정의하지 말고 hashCode()메소드도 재정의해서 논리적 동등 객체일경우 동일한 해시코드가 리턴되도록 해야한다.

'Java' 카테고리의 다른 글

자료구조 Array 구현  (0) 2022.03.23
Java JVM메모리 구조  (0) 2021.12.24
Java Jsoup,Selenium 크롤링 하기  (0) 2021.12.14
Array,List,ArrayList 의 차이  (0) 2021.12.01