자바에서 동등성(equality)을 보장하는 equals()와 hashCode()가 존재합니다.
이 두 메소드는 Object 클래스에서 기본적으로 제공을 하며 객체의 동등성 비교를 할 수 있습니다.
equals()
두 객체의 참조 동등성(reference equality)을 검사합니다.
두 객체가 같은 메모리 주소를 가리키고 있는지 확인을 하며 같다면 true 다르다면 false를 반환하게 됩니다.
Object obj1 = new Object();
Object obj2 = new Object();
System.out.println(obj.equals(obj2)); // false
사실 저는 실제 값이 같아야 equals가 true 일 줄 알았지만 실제로는 같은 주소인지를 확인하는 것이였습니다.
이유는 equals를 처음보고 계속 사용했던 순간은(오버라이딩 제외) String 문자열을 비교할 때 사용했었기 때문입니다.
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
return (anObject instanceof String aString)
&& (!COMPACT_STRINGS || this.coder == aString.coder)
&& StringLatin1.equals(value, aString.value);
}
사실 알고 보니 String 클래스 또한 오버라이딩을 하여 메모리 주소 값을 비교하는 것이 아닌 값을 통해 비교한다는 것을 알게 되었습니다.
즉 오버라이딩을 하지 않는 이상 equals() 는 메모리 주소를 비교하여 true/false를 반환합니다.
hashCode()
객체의 해시값을 반환합니다. 데이터 구조 HashMap, HashSet에서 객체를 식별하거나 빠르게 검색할 때 사용됩니다.
Object 클래스의 기본 hashCode()는 객체의 메모리 주소를 기반으로 해시값을 생성합니다.
해시(Hash)에 대해 간단히 설명하면, 특정 값을 해시 함수에 입력하면 고정된 범위의 값(해시 값)이 생성됩니다. 예를 들어, 1000이라는 값을 해시 함수에 넣었을 때 1이라는 값이 반환되고, 1101을 넣었을 때 100이 반환될 수 있습니다. 해시 함수는 큰 범위의 값을 작은 범위로 축소합니다. 이 과정에서 서로 다른 입력값(예: 1205와 1101)이 동일한 해시 값(예: 100)을 생성하는 해시 충돌이 발생할 수 있습니다. 이를 방지하거나 최소화하기 위해 적절한 해시 함수와 충돌 처리 방법이 필요합니다.
즉 hashCode()를 통해 동등성을 검사하는 것은 메모리 주소를 기반으로 계산된 해시 값을 반환합니다.
이 때 해시 충돌이 발생할 수 있어 메모리 주소가 다른 객체도 같은 hashCode가 나올 수 있습니다.
정리
equals() : 다른 객체일 때 무조건 false
hashCode() : 다른 객체일 때 true 일 수도 있다
'Java' 카테고리의 다른 글
[Java] String, StringBuffer, StringBuilder 차이점 (1) | 2025.01.03 |
---|---|
[Java] 인스턴스 내부 클래스 (0) | 2024.12.05 |
[Java] for-each 루프 (0) | 2024.12.04 |
[Java] 리스트 인터페이스 구현 (3) | 2024.11.26 |
[Java] 1급 커넥션 (0) | 2024.10.14 |