JAVA

두 객체가 동일한 HashCode를 가지면?

D_Helloper 2023. 5. 27. 17:02

equals()와 hashCode는 모든 Java 객체의 부모인 Object 클래스에 정의되어 있기 때문에, Java의 모든 객체는 Object 클래스의 equals와 hashCode()를 상속받음

동일성 : 주소 값을 비교 ( == )

동등성 : 객체 내부의 값을 비교 (equals와 hashCode를 재정의 하여 비교)

equals() ?

  • 2개의 객체가 동일한지 검사하기 위해 사용
  • 기본적으로 주소 값을 비교하여 같은 메모리 주소를 가진 경우에 동일하다고 판단
public boolean equals(Object obj) {
    return (this == obj);
}

hashCode() ?

  • 객체의 HashCode란 객체를 식별할 하나의 정수 값을 의미
  • hashCode()는 객체의 HashCode를 리턴
  • 두 객체가 동일 객체인지 비교할 때 사용할 수 있음
public class Object {
	 ...
	
	public native int hashCode();
}

위 상황에서 다른 객체들이 동일한 해시코드를 가질 수 있음 = 해시 충돌

만약 해시 충돌이 발생한 경우에 동등성을 비교하고자 한다면 참이 아님

public class Book {
    private String title;
    private String author;

    public Book(String title, String author) {
        this.title = title;
        this.author = author;
    }

    @Override
    public int hashCode() {
        // 동일한 hashCode를 반환하는 간단한 예제
        return 42;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;

        if (obj == null || getClass() != obj.getClass())
            return false;

        Book other = (Book) obj;
        return title.equals(other.title) && author.equals(other.author);
    }
}
  • 위의 경우 항상 HashCode는 42를 반환하도록 구현
  • Book 객체를 만들 때 마다 동일한 해시 코드를 가지도록 함(해시 충돌 발생)
  • 하지만 equals()를 재정의 하여 title과 author 필드를 비교함으로써 동등성을 판단하도록 구현
  • 따라서, 아래의 상황에서는 거짓
Book book1 = new Book("Title 1", "Author 1");
Book book2 = new Book("Title 2", "Author 2");

System.out.println(book1.hashCode());  // 42
System.out.println(book2.hashCode());  // 42

System.out.println(book1.equals(book2));  // false