To Dare Is To Do!
hashcode(), equals() 본문
equals()
어떤 두 참조 변수의 값이 같은지 다른지 동등 여부
public boolean equals(Object obj) {
return (this == obj);
}
재정의하지 않은 equals() 메서드는 호출한 객체와 전달된 객체의 내용이 같은지 확인하며 == 연산자를 사용해 동일한 참조를 가리키면 true를 반환함
equals() 오버라이딩
논리적 동등성을 비교하고자 할 때, equals()를 오버라이딩하여 객체의 특정 필드를 기준으로 비교
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null || getClass() != obj.getClass()) return false;
MyObject myObject = (MyObject) obj;
return field1.equals(myObject.field1) && field2 == myObject.field2;
}
hashCode()
어떤 두 참조 변수의 주소값으로 만든 고유한 해시값이 동일한 비교
public native int hashCode();
hashCode() 메소드는 객체의 고유한 해시 코드를 반환하며, 해시는 주로 객체의 메모리 주소에 해시 함수를 적용한 값으로 해시 기반 컬렉션HashMap HashSet 을 구현하여 객체를 빠르게 검색하고 저장하기 위해 사용 (heap에 저장된 객체의 메모리 주소 반환)
hashCode() 오버라이딩
hashCode() 를 재정의할 경우, 동일 객체는 동일 해시 코드를 반환하도록 재정의
@Override
public int hashCode() {
return Objects.hash(field1, field2);
}
equals()와 hashCode()의 관계
- equals()가 true를 반환하는 두 객체는 동일한 해시 코드를 반환해야 일관성이 유지됨
→equals() 메서드로 객체를 비교하는 정보가 변하지 않았다면, hashCode() 메서드는 일관된 해시 코드를 반환해야 함
- equals() 메서드로 비교했을 때 객체가 같다면, hashCode() 메서드는 같은 해시 코드를 반환해야 함
→ equals() 의 결과가 true인 두 객체의 해시코드는 반드시 같아야한다는 자바의 규칙 때문
- equals() 메서드로 비교했을 때 객체가 다르다면, hashCode() 메서드는 다른 해시 코드를 반환할 필요는 없지만, 해시 테이블의 성능 향상을 위해 다른 해시 코드를 반환하는 것이 좋음
해시 테이블의 동작 방식
해시 테이블은 키-값 쌍을 저장하는 자료 구조로, 키의 해시 코드를 이용해 값을 빠르게 검색할 수 있도록 설계되어있음
- 해시 코드 생성 : 키 객체의 hashCode() 메서드를 호출하여 해시 코드를 생성
- 버킷 결정 : 생성된 해시 코드를 이용해 데이터를 저장할 버킷(배열의 인덱스)을 결정
- 저장 및 검색 : 같은 버킷에 여러 개의 키-값 쌍이 저장될 수 있으며, 이를 해결하기 위해 각 버킷은 연결 리스트, 트리 등의 구조로 관리됨
equals()와 hashCode()의 역할
- equals() 메서드 : 두 객체가 논리적으로 같은지 비교
- hashCode() 메서드 : 객체의 해시 코드를 반환
성능과 해시 충돌
- 해시 충돌 : 해시 충돌이 발생하면, 다른 객체들이 같은 버킷에 저장이 됨,
- 이 경우, 연결 리스트나 트리의 형태로 객체들이 관리되기 때문에 검색 성능이 떨어질 수 있다.
- 해시 코드 분포 : 해시 테이블의 성능은 해시 코드의 분포에 크게 영향을 받는데, 해시 코드가 고르게 분포될수록 해시 충돌이 적게 발생하고, 검색 성능이 향상됨
설명
- equals() 메서드로 두 객체가 다르다고 판단되면, 논리적으로 다른 객체가 됨
- 이 경우, 두 객체의 hashCode() 값이 반드시 달라야 하는 것은 아니므로 동일한 해시 코드를 반환해도 해시 테이블은 정상적으로 동작하지만, 같은 해시 코드를 가진 객체들이 같은 버킷에 저장되므로 해시 충돌이 발생할 수 있음
- 해시 충돌이 많아지면, 같은 버킷에서 여러 객체를 비교해야 하므로 검색 성능이 저하될 수 있음
- 따라서, 다른 객체에 대해 다른 해시 코드를 반환하는 것이 좋고, 이는 해시 충돌을 줄이고 해시 테이블의 검색 성능을 향상시키는 데 도움이 됨
요약
- equals() 메서드로 다르다고 판단되는 객체들은 같은 hashCode() 값을 가질 수 있지만, 성능을 위해 다른 해시 코드를 가지는 것이 좋음
- 해시 코드를 잘 분포시키면 해시 테이블의 성능이 향상되고 이를 위해 hashCode() 메서드를 효율적으로 재정의하는 것이 중요
해시 기반 컬렉션에서 equals와 hashcode의 관계가 중요한 이유
- 해시 기반 컬렉션(HashMap, HashSet)에서 객체를 효율적으로 저장하고 검색하기 위해 일관성 필요
- equals()를 재정의할 때 hashCode()도 재정의하지 않으면, 해시 기반 컬렉션에서 제대로 동작하지 않을 수 있음
equals()는 객체의 논리적 동등성을 정의하고 비교
hashCode()는 객체를 해시 기반 컬렉션에서 효율적으로 저장하고 검색하기 위한 해시 코드 제공
두 메서드는 일관성을 유지하기 위해 함께 오버라이딩 필요
'Java' 카테고리의 다른 글
Stream (0) | 2024.08.07 |
---|---|
thread pool (3) | 2024.08.06 |
StringBuffer, StringBuilder, string (0) | 2024.08.04 |
동일성과 동등성 (0) | 2024.07.30 |
Call by value와 Call by reference (0) | 2024.07.29 |