JAVA | 객체 비교하기 - equals()와 hashCode() 재정의

728x90

JAVA | 객체 비교하기 - equals()와 hashCode() 재정의

💡 객체는 매번 생성할 때 다른 해시코드를 갖고 다른 주소값을 갖는 다른 객체로 분류된다. 그런데 만약 객체의 필드가 같을 때 동일한 객체로 처리하고 싶으면 어떻게 해야 할까 ? equals 와 hashCode()를 해당 클래스에서 재정의해서 사용하면 된다!

우리가 자바에서 흔히 사용하는 HashMap, HashSet 등의 자료구조는 내부적으로 객체를 비교할 때 해당 객체의 해쉬값을 사용하여 비교를 하기 때문에 이번 기회에 잘 알아두고 써먹자.

◼️ equals 메소드 재정의 하는 법

  • 아래의 코드와 같이, 우선 비교하고자 하는 클래스 타입인지를 instanceof로 확인한다.
  • 나의 경우에는 두 객체가 갖는 x, y값이 각각 같다면 두 객체는 동일한 객체로 판단하고 싶었다. 그에 따른 코드이다.
@Override
	public boolean equals(Object obj) {
		// TODO Auto-generated method stub
		if(obj instanceof Point) {
			Point o = (Point)obj;
			return this.x == o.x && this.y == o.y;
		}
		return false;
	}

◼️ hashcode 메소드 재정의 하는 법

equals 메소드를 이용해 객체를 비교할 수도 있지만, 필드 값이 같은 두 객체를 진정으로 같게 보기 위해서는 hashcode 메소드도 함께 재정의 해야 한다.

우리는 클래스 안에 hashCode 메소드를 오버라이드 하여 멤버 변수를 Objects의 hash메소드의 인자로 넘겨줌으로써 손쉽게 hashcode를 재정의 할 수 있다.

	@Override
	public int hashCode() {
		// TODO Auto-generated method stub
		return Objects.hash(x, y); //x, y 값을 동일하게 갖는 객체는 동일 해시코드 가짐
		/**
		 * 클래스가 여러 가지 필드를 가지고 있을 때 필드들로부터 해시코드를 생성하면
			동일한 필드값을 가지는 객체는 동일한 해시코드를 가질 수 있습니다. 
		 */
	}

◼️  아래의 코드로 실제 main에서 어떻게 동작하는지 확인해보자.

실제로 위와같이 두 메소드를 재정의 한 뒤, map에 new Point(1, 0)을 갖는 애를 여러 번 계속해서 담아줘도, 해당 map의 사이즈는 1이었다.

이 뜻은 매번 생성하는 객체를 다르게 보는게 아니라, 좀전에 재정의해준 equals()와 hashCode()에 따라 두 필드값만 같다면 아무리 새롭게 생성해도 그 객체는 동일 객체로 간주하게 됐다는 뜻이다.

실행 결과

728x90