윤개발

Java의 Equals와 Hashcode 본문

백엔드/Java

Java의 Equals와 Hashcode

DEV_SJ 2021. 4. 27. 15:29

Java를 처음 접할때 배우는 메소드임에도 잘 모르고 쓰는 경우가 많은 Equals와 Hashcode에 대해서 알아보자.

 

두 메소드는 모든 객체의 부모인 Object 클래스에 구현되어있다. Objcect의 구현된 소스코드를 살펴보자.

 

// Indicates whether some other object is "equal to" this one.
public boolean equals(Object obj) {
	return (this == obj);
}

Object 클래스에 구현된 equals 클래스이다. 생각보다 코드가 단순하고 객체 자체가 같은지를 비교하는 코드이다.

 

다음은 hashcode이다. hashcode는 따로 작성된 코드가 없이 native라는 코드가 붙어있다.

/**
* Returns a hash code value for the object. This method is
* supported for the benefit of hash tables such as those provided by {@link java.util.HashMap}.
**/
public native int hashCode();

hashcode는 항상은 아니지만 힙에 저장되어있는 객체의 고유 주소값을 반환한다.

 

두 메서드는 오버라이딩해서 쓸수가 있다. 하지만 이펙티브 자바의 "[ITEM10] equals는 일반 규약을 지켜 재정의하라." 에서는 재정의를 하지 않는것을 추천한다.

 

equals 메서드는 재정의하기 쉬워보이지만 곳곳에 함정이 있어 큰 문제가 될 수 있다. 아래 상황에 해당한다면 재정의 하지 않는것이 최선이다.

  1. 각 인스턴스가 본질적으로 고유하다. 값을 표현하는게 아니라 개체를 표현하는 클래스가 해당된다.
  2. 인스턴스의 논리적 동치성을 검사할 일이 없다.
  3. 상위 클래스에서 재정의한 equals가 하위 클래스에도 딱 들어맞는다.
  4. 클래스가 private 여서 equals를 호출할 일이 없다.

결론적으로 두 메서드 다 객체가 동일한지 보는 것이다.

 

단 객체의 값이 동일한지 알고 싶을 경우에는 equals 함수를 오버라이딩 할 수 있다.

 

Null체크를 하고, 타입이 같은지 확인하고, 값을 확인한다.

 

이렇게 equals 가 오버라이딩 된 객체는 String 객체가 있다. 

 

String 객체는 값이 같은지 비교하는 오버라이딩 함수가 작성되어있다.

public boolean equals(Object anObject) {
	if (this == anObject) {
		return true;
	}
	if (anObject instanceof String) {
		String anotherString = (String)anObject;
		int n = value.length;
		if (n == anotherString.value.length) {
			char v1[] = value;
			char v2[] = anotherString.value;
			int i = 0;
			while (n-- != 0) {
				if (v1[i] != v2[i])
					return false;
					i++;
            }
			return true;
		}
    }
	return false;
}

 

또한 equals를 재정의 하였다면 hashcode도 재정의 하여야한다.

 

equals를 통해 같은 값으로 나왔다면 hashcode의 결과도 같은 값으로 나와야하기 때문이다.

 

hashset 과 같은 함수에 저장을 해야할 경우 equals에서 동등하다고 나왔어도 hashcode를 오버라이딩 하지 않으면

 

동일한 객체로 인식하지 못해 2가지가 모두 삽입된다.

 

'백엔드 > Java' 카테고리의 다른 글

DIP 아키텍처 설계  (0) 2021.08.03
Java Garbage Collection 이란?  (0) 2020.11.12
Comments