equals()
equals()는 보통 동일한 객체인지 확인할 때 사용한다.
- 항상 그런 것은 아니다. String의 경우 문자열이 동일한지 확인할 때 사용
// Object의 equals()
public boolean equals(Object obj) {
return (this == obj);
}
hashCode
객체 해시코드란 객체를 식별하는 하나의 정수값을 말한다. Object의 hashCode() 메소드는 객체의 메모리 번지를 이용해서 해시코드를 만들어 리턴하기 때문에 객체 마다 다른 값을 가지고 있다. 객체의 값을 동등성 비교시 hashCode()를 오버라이딩할 필요성이 있는데, 컬렉션 프레임워크에서 HashSet, HashMap, HashTable은 다음과 같은 방법으로 두 객체가 동등한지 비교한다.
hashCode()
메소드를 실행해서 리턴된 해시코드 값이 같은지를 본다. 해시 코드값이 다르면 다른 객체로 판단하고, 해시 코드값이 같으면
equals()
메소드로 다시 비교한다. 이 두개가 모무 맞아야 동등 객체로 판단한다. 즉, 해시코드 값이 다른 엔트리끼리는 동치성 비교를 시도조차 하지 않는다.
equals()와 hashCode()의 관계
- equals()를 재정의(override)할 때는, hashCode()도 재정의해야 한다. (항상 함께 재정의)
- equals()의 값이 true이면, hashCode()도 동일한 값을 가져야 한다.
- 반대로 equals() 값이 false이면, hashCode()도 다른 값을 가져야 한다.
equals() 와 hashCode()를 같이 재정의 해야 하는 이유
만약 equals()와 hashCode() 중 하나만 재정의 하면 어떻게 될까? 위 예에서도 봤듯이 hashCode()를 재정의 하지 않으면 같은 값 객체라도 해시값이 다를 수 있다. 따라서 HashTavble에서 해당 객체가 저장된 버킷을 찾을 수 없다.
반대로 equals()를 재정의하지 않으면 hashCode()가 만든 해시값을 이용해 객체가 저장된 버킷을 찾을 수는 있지만 해당 객체가 자신과 같은 객체인지 값을 비교할 수 없기 때문에 null을 리턴하게 된다. 따라서 역시 원하는 객체를 찾을 수 없다.
이러한 이유로 객체의 정확한 동등 비교를 위해서는(특히 Hash 관련 컬렉션 프레임워크를 사용할때) Object의 equals()메소드만 재정의하지 말고 hashCode()메소드도 재정의해서 논리적 동등 객체일 경우 동일한 해시코드가 리턴되도록 해야한다.
'Java' 카테고리의 다른 글
[Java] Try-catch 문이란? (예외처리) (0) | 2022.10.17 |
---|---|
[Java] Enum (0) | 2022.10.06 |
[Java] toString() 메서드 (0) | 2022.10.06 |
[자바] super와 super() (0) | 2022.10.02 |
[자바] 오버라이드(Override) (0) | 2022.10.01 |