Notice
Recent Posts
Recent Comments
Link
«   2025/07   »
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31
Tags
more
Archives
Today
Total
관리 메뉴

To Dare Is To Do!

hashcode(), equals() 본문

Java

hashcode(), equals()

Nick_Choi 2024. 8. 4. 14:57

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() 메서드는 다른 해시 코드를 반환할 필요는 없지만, 해시 테이블의 성능 향상을 위해 다른 해시 코드를 반환하는 것이 좋음

 

해시 테이블의 동작 방식

해시 테이블은 키-값 쌍을 저장하는 자료 구조로, 키의 해시 코드를 이용해 값을 빠르게 검색할 수 있도록 설계되어있음

  1. 해시 코드 생성 : 키 객체의 hashCode() 메서드를 호출하여 해시 코드를 생성
  2. 버킷 결정 : 생성된 해시 코드를 이용해 데이터를 저장할 버킷(배열의 인덱스)을 결정
  3. 저장 및 검색 : 같은 버킷에 여러 개의 키-값 쌍이 저장될 수 있으며, 이를 해결하기 위해 각 버킷은 연결 리스트, 트리 등의 구조로 관리됨

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