equals()
와 hashCode()
는 모든 Java 객체의 부모인 Object
클래스에서 상속받습니다. 이 메서드들은 객체의 비교와 해시 기반 자료구조에서 중요한 역할을 합니다.
equals()
는 두 객체가 같은지 확인하는 메서드로, 기본적으로 메모리 주소(동일성)를 비교합니다. 예를 들어, 두 문자열 객체가 같은 값을 가지더라도 메모리 주소가 다르면 false
를 반환합니다.
public boolean equals(Object obj) {
return (this == obj); // 주소 비교
}
하지만 프로그래밍에서 두 객체의 필드 값이 같으면 논리적으로 동일한 것으로 취급해야 할 때가 있습니다. 이를 위해 equals()
를 오버라이드하여, 객체의 필드를 기준으로 동등성(Equality)을 비교하도록 설정할 수 있습니다. 예를 들어, String
클래스는 문자열 값을 비교하는 방식으로 equals()
를 재정의하고 있습니다.
String s1 = new String("Test");
String s2 = new String("Test");
System.out.println(s1 == s2); // false, 주소 비교
System.out.println(s1.equals(s2)); // true, 값 비교
위 코드는 String
클래스에서 equals()
메서드를 오버라이드하여 값으로 비교하게 만든 예입니다.
hashCode()
메서드는 객체의 고유한 해시코드를 반환합니다. 기본적으로 Object
클래스에서는 객체의 메모리 주소를 기반으로 해시 코드를 반환하지만, 객체의 값을 기준으로 해시코드를 생성하는 방식으로 오버라이드할 수 있습니다.
public native int hashCode();
이 메서드는 해시 기반 자료구조(예: HashMap
, HashSet
)에서 객체의 위치를 결정하는 데 중요한 역할을 합니다.
두 객체가 equals()
에 의해 같다면, 이들은 반드시 동일한 hashCode()
값을 가져야 합니다. 그렇지 않으면, 해시 기반 자료구조에서 문제가 발생할 수 있습니다. 반대로, hashCode()
가 같다고 해서 equals()
가 true
를 반환할 필요는 없습니다. 이 관계는 해시 기반 컬렉션에서 정확한 동작을 보장합니다.
예를 들어, Employee
클래스를 정의하여 id
필드가 같으면 같은 객체로 인식되도록 equals()
를 오버라이드할 수 있습니다.
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Employee e = (Employee) o;
return this.getId().equals(e.getId());
}
hashCode()
역시 id
를 기준으로 생성하여 해시 기반 자료구조에서도 동일한 객체로 인식되도록 해야 합니다.
@Override
public int hashCode() {
return Objects.hash(getId());
}
이렇게 하면 HashSet
과 같은 자료구조에서 객체의 중복 저장을 방지할 수 있습니다.
Reference