멘토링

hashCode()와 equals() 메소드

langsamUndStetig 2022. 6. 17. 20:00

오버라이딩 하기 전의 equals() 메소드는 내부에서 "==" 연산자를 호출하여  비교를 한 후 boolean 값을 리턴해준다.

hashCode() 메소드는 public native int hashCode();로 선언되어 있다.

* native 키워드를 사용하면, 시스템의 성능 향상, 기계 수준 혹은 메모리 수준의 의사소통 달성, 이미 존재하는 레거시 논 자바 코드를 사용할 수 있다.

package basic;


import java.util.*;

public class Main {
  int a;
  public Main(int a) {
    this.a = a;
  }


  @Override
  public int hashCode() {
    return Objects.hash(a);
  }
  @Override
  public boolean equals(Object o) {
    if (this == o) return true;
    if (o == null || getClass() != o.getClass()) return false;
    Main main = (Main) o;
    return a == main.a;
  }

 public static void main(String[] args) {
    Main a = new Main(5);
    Main b = new Main(5);
    // equals()랑 hashCode()를 overriding 하지 않으면
    // equals()는 false, hashCode()는 다른 int 값을 출력
    System.out.println(a.equals(b)); // 기존의 equals()는 "==" 연산자와 동일하게 작동한다.
    System.out.println(b.equals(a));
    System.out.println(a.hashCode());
    System.out.println(b.hashCode());
// equals()랑 hashCode()는 같이 묶어서 overriding을 해준다.
    // equals()만 하면 무슨 문제가 일어날까??
    // list는 값의 중복이 허용된다. 반면 set는 값의 중복이 허용되지 않는다.
    // 그런데 HashSet()으로 set의 객체를 생성하면, HashSet은 Hash 값을 가지고, 같은 값인지 아닌지를 확인한다.
    // hashCode()값이 다르면 equals()가 true를 반환하더라도 다른 값으로 판단하여 두 개의 중복된 값이 set에 추가가 된다.
    // 반면 두 메소드를 overriding하면 set엔 중복된 값 중 한 개만 저장되게 된다.
    // hashCode()만 overriding 한 경우엔 hashCode()값은 동일하게 나왔지만, equals()에선 false가 나왔고, HashSet에도 값이 중복으로 들어갔다.
    List<Main> li = new ArrayList<>();
    li.add(a);
    li.add(b);
    System.out.println(li.size());

    Set<Main> sets = new HashSet<>();
    System.out.println(sets.add(a)); // true
    System.out.println(sets.add(b)); // false
    System.out.println(sets.size()); // 1
  }

}