음 이걸 적게된건 단순하게 equals와 hashcode에 관련된 글을 우연히 보게 되었다.

 

equals는 항상 자주 쓰는거라 그렇다 치는데 hashcode는 메서드를 직접 잘 사용하지 않는다.

 

대신에 hashcode와 관련된 컬랙션  ( 예: HashMap, HashSet, Hashtable) 를 주로 사용한다.

(자세히 안 알아본 내 잘못이 크다.  자료구나, 알고리즘 공부하면 당연하게 hashmap을 사용해서 너무 쉽게 봤던것 같다.)

그렇다면 하나씩 확인해보자.

equals() 메소드

equals() 메소드는 두 객체가 "논리적으로 같은지"를 비교합니다. 기본적으로 Object 클래스의 equals() 메소드는 두 객체의 참조를 비교하지만, 이를 오버라이드하여 객체의 속성을 비교할 수 있습니다.

@Override
public boolean equals(Object obj) {
    if (this == obj) return true;
    if (obj == null || getClass() != obj.getClass()) return false;
    MyClass myClass = (MyClass) obj;
    return field1 == myClass.field1 &&
           Objects.equals(field2, myClass.field2);
}

 

hashCode() 메소드

hashCode() 메소드는 객체의 해시 코드를 반환합니다. 이 값은 객체를 해시 기반 컬렉션에서 사용할 때 사용됩니다. hashCode() 메소드를 오버라이드할 때는 equals() 메소드도 함께 오버라이드해야 하며, 이 둘은 다음 계약을 준수해야 합니다:

  1. 일관성: 같은 객체에 대해 여러 번 호출된 hashCode()는 항상 같은 값을 반환해야 합니다.
  2. equals()와의 일관성: 두 객체가 equals() 메소드로 같다고 판별되면, 그들의 hashCode()는 반드시 같아야 합니다.
  3. 다름: 두 객체가 equals() 메소드로 다르다고 판별되더라도, hashCode() 값이 반드시 다를 필요는 없습니다. 그러나 다른 객체에 대해서는 가능한 한 다른 해시 코드를 반환해야 합니다.
@Override
public int hashCode() {
    return Objects.hash(field1, field2);
}

예제 클래스

다음은 equals()와 hashCode() 메소드를 오버라이드한 예제 클래스입니다:

import java.util.Objects;

public class MyClass {
    private int field1;
    private String field2;

    public MyClass(int field1, String field2) {
        this.field1 = field1;
        this.field2 = field2;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        MyClass myClass = (MyClass) o;
        return field1 == myClass.field1 && Objects.equals(field2, myClass.field2);
    }

    @Override
    public int hashCode() {
        return Objects.hash(field1, field2);
    }
}

 

뭐 사실 equals는 워낙 자주 사용하다보니 잘알것이다. 다만 hashcode는  한번쯤 무엇인지 확인해볼필요가 있다.

 

hashCode() 메소드는 주로 해시 기반 컬렉션 (예: HashMap, HashSet, Hashtable)에서 객체를 효율적으로 저장하고 검색하기 위해 사용됩니다.

 

일반적으로  List< HashMap> 을 자주 이용한다. 이때 hashMap의 객체의 효율적인 저장과 검색을 위해서 사용을한다. 

주요 이유

  1. 빠른 데이터 검색: 해시 기반 컬렉션은 평균적으로 O(1) 시간 복잡도로 데이터를 검색할 수 있습니다. 이는 객체의 해시 코드를 사용하여 해당 객체가 위치한 버킷을 빠르게 찾을 수 있기 때문입니다.
  2. 효율적인 데이터 저장: 해시 코드를 사용하면 데이터를 저장할 때 충돌을 줄일 수 있습니다. 해시 코드가 잘 분포되면 서로 다른 객체가 동일한 버킷에 저장되는 경우가 줄어들어, 해시 테이블의 성능이 향상됩니다.
  3. 일관성: equals() 메소드와 함께 사용될 때, 해시 코드는 객체의 논리적 동등성을 일관되게 유지하는 데 도움을 줍니다. 동일한 객체는 항상 동일한 해시 코드를 가져야 하며, 그렇지 않으면 해시 기반 컬렉션의 동작이 올바르게 작동하지 않을 수 있습니다.

여기서 hashcode는 메모리 주소가 아니다. 처음에 필자는 메모리 주소 인가 했다.

 

hashCode()와 객체 주소의 관계

  1. 기본 구현:
    • Object 클래스의 기본 hashCode() 메소드 구현은 객체의 메모리 주소를 기반으로 해시 코드를 생성할 수 있습니다. 이 때문에 객체가 동일하더라도 메모리 위치가 달라지면 해시 코드가 달라질 수 있습니다. 그러나, 이 기본 구현은 대부분의 경우 재정의됩니다.
  2. 사용자 정의 구현:
    • 대부분의 경우, 특히 해시 기반 컬렉션에서 올바르게 동작하기 위해, hashCode() 메소드는 객체의 상태(예: 필드 값)에 기반하여 해시 코드를 생성하도록 오버라이드됩니다. 이 경우, hashCode()는 객체의 메모리 주소와는 무관하게 객체의 내용을 기반으로 해시 코드를 계산합니다

'프로그래밍언어 > JAVA' 카테고리의 다른 글

Virtual Thread(가상 스레드)  (0) 2024.09.01
Hibernate ?  (0) 2024.03.31
순수 JAVA JPA  (0) 2024.03.17
getDeclaredConstructor().newInstance()?  (0) 2024.03.16
Reflection API란?  (0) 2024.03.16

+ Recent posts