JAVA - 객체간 비교 ( equals() , hashCode() )

TopOfTheHead·2025년 9월 25일

자바 ( JAVA )

목록 보기
14/23

Collection

JAVA에서 해시를 기반으로 Key - Value 쌍 데이터를 저장하는 자료구조 ( ex. HashSet , HashMap )에서 Key Type을 특정 클래스로 지정 및 Key 객체를 활용해 Value를 찾을 경우

。단순하게 인스턴스 멤버가 동일한 Key 객체를 통해 검색 시 Value를 return 받을 수 없다.

import java.util.Map;
import java.util.HashMap;
class KeyClass {
	private final int id1 ;
	private final int id2 ;
	public KeyClass(int id1 , int id2) {
		this.id1 = id1;
		this.id2 = id2;
	}
}
public class testcase1  {
	public static void main(String[] args) {
		Map<KeyClass , String> map = new HashMap<KeyClass , String>();
		map.put(new KeyClass(1,1), "lee");
		System.out.println(map.get(new KeyClass(1,1))); // null 출력
	}
}

map.get(객체)를 통해 객체간 비교로 해당하는 데이터를 찾을 때 단순하게 참조형 변수를 비교하여 객체가 저장된 Heap영역주소의 비교를 수행
▶ 내부 인스턴스변수 등의 요소가 동일한 객체로 검색을 수행해도 객체참조주소가 다르므로 검색이 불가능.

KeyClass 내에 equals() , hashCode()를 함께 추가로 메소드 오버라이딩하여 해시값을 사용하는 자료구조 내에서 논리적인 동일객체여부를 판단
해시기반 자료구조가 아닌경우 equals()만 구현

import java.util.Map;
import java.util.HashMap;
import java.util.Objects;
class KeyClass {
	private final int id1 ; // 불변변수
	private final int id2 ;
	public KeyClass(int id1 , int id2) {
		this.id1 = id1;
		this.id2 = id2;
	}
	@Override
	public int hashCode() {
		// 객체 내 인스턴스변수값을 int의 해시값으로 만든 후 return
    	// Hash 자료구조 에서 객체 비교 수행 시 해당 해시값으로 비교
		return Objects.hash(id1, id2);
	}
	@Override
	public boolean equals(Object obj) {
		// 객체의 메모리주소값이 동일한 경우 true 반환
		if ( this == obj ) return true;
		if ( obj instanceof KeyClass k )
			// 객체 내부 인스턴스변수가 동일한 경우 true 반환
			return this.id1 == k.id1 && this.id2 == k.id2;
		// 두 객체가 동일하지 않은 경우 false 반환
		return false;
	}
}
public class testcase1  {
	public static void main(String[] args) {
		Map<KeyClass , String> map = new HashMap<KeyClass , String>();
		map.put(new KeyClass(1,1), "lee"); 
		System.out.println(map.get(new KeyClass(1,1))); // lee 출력
	}
}

해시기반자료구조에서 객체를 비교하는 원리
HashMap , HashSet의 경우 자료구조객체.get(키객체)를 통해 전달된 Key객체를 다음 2단계를 거쳐 자료구조객체의 비교를 수행 후 존재하면 Value를 return한다.
▶ 다음 단계에서 일치하지 않는경우 자료구조 내 다음 키객체와 비교 수행

1. Key 객체hashCode()에서 return되는 int해시값을 통해 입력된 키객체와 저장된 키객체해시값이 일치하는지 판단

2. 해시값이 동일한 경우 두 객체equals()를 통해 비교 후 동일한 경우 해당하는 Value 반환
equals()로 동일한 객체hashCode()해시값도 동일해야함.

hashCode() :
객체해시값을 반환하는 method
▶ 보통 Objects.hash(인스턴스변수1,...)해시값을 생성하여 return.

java.lang.Object 클래스Method로서 메소드 오버라이딩을 통해 재정의하여 해시값을 반환

클래스HashSet , HashMapGeneric에 정의된 경우 해당 자료구조해시값을 통해 클래스 객체 간 비교를 수행하므로 해당 클래스hashCode()를 구현해야한다.

    @Override
	public int hashCode() {
		// 객체 내 인스턴스변수값을 int의 해시값으로 만든 후 return
    	// Hash 자료구조 에서 객체 비교 수행 시 해당 해시값으로 비교
		return Objects.hash(id1, id2);
	}

Objects.hash(변수1, 변수2,...) : java.util.Objects
。복수의 변수를 기반으로 해시코드를 생성

equals(객체)
객체를 비교하는 메소드
java.lang.Object 클래스Method로서 메소드 오버라이딩을 통해 재정의하여 비교 결과를 boolean으로 return
Stringequals()도 동일하게 메소드 오버라이딩으로 구현한 메소드로서 두개 문자열의 비교를 수행

	@Override
	public boolean equals(Object obj) {
		// 객체의 메모리주소값이 동일한 경우 true 반환
		if ( this == obj ) return true;
        // obj가 KeyClass 객체인 경우 KeyClass로 캐스팅 후 변수 k로 할당
		if ( obj instanceof KeyClass k )
			// 객체 내부 인스턴스변수가 동일한 경우 true 반환
			return this.id1 == k.id1 && this.id2 == k.id2;
		// 두 객체가 동일하지 않은 경우 false 반환
		return false;
	}
  • 객체 instanceof 클래스
    ObjectType으로 선언된 객체특정 클래스 또는 특정 인터페이스에 소속하는지 객체 여부를 확인 후 boolean을 return하는 연산자

  • 패턴매칭
    객체 instanceof 클래스를 사용 시 해당 클래스에 해당하는 경우 명시적 캐스팅 없이 객체클래스캐스팅하여 할당하도록 축약한 문법
    Java 16에서 도입
if (obj instanceof KeyClass) {
    KeyClass k = (KeyClass) obj; // 명시적 캐스팅
    return this.id1 == k.id1 && this.id2 == k.id2;
}
if (obj instanceof KeyClass k)
    return this.id1 == k.id1 && this.id2 == k.id2;
profile
공부기록 블로그

0개의 댓글