📜 제목으로 보기

동일(ㅣ)성 = (I)dentity = 메모ㄹ(ㅣ)주소

  • 반대로 동등성 = equality = 정해준 값이 같은지

  • equals는 equality가 아닌메모리 주소(identity) 비교가 default라서 오버라이딩 해야한다.

    • == = 메모리 주소로 비교 = default equals

        public boolean equals(Object obj) {
            return (this == obj);
        }
      
    • = = 으로 비교 = 오버라이딩 equals

세팅

public class Car {
    private final String name;
    private int position;

    // 부 생성자는 주 생성자(name, position)보다 더 앞에 위치하며, 뒤쪽의 주 생성자를 this( , )로 사용한다.
    public Car(final String name) {
        this(name, 0);
    }

    public Car(final String name, final int position) {
        this.name = name;
        this.position = position;
    }
}

오버라이딩 전 default equals -> 메모리비교

@Test
void before_overriding_equals_test() {
    //1. 오버라이딩 전 deafult equals : 같은 메모리 주소만 true
    final Car 재성 = new Car("차");
    final Car 석영 = new Car("차");

    assertThat(재성).isEqualTo(석영);
    //Expected :domain.Car@29647f75
    //Actual   :domain.Car@355ce81c
    // -> 서로 다른 객체(메모리주소)를 가져서 deafult equals로는 같다고 할 수 없음.
}

오버라이딩후 equals -> 지정한 값으로 비교

final Car 재성 = new Car("차");
final Car 석영 = new Car("차");

assertThat(재성).isEqualTo(석영); // true

hashCode도 같이 오버라이딩 하는 이유?

  • hashCode메서드는 실제 메모리 주소 -> 정수값으로 반환해주는 함수이다.
    • 자료구조 등에 사용될 때, 이 hashCode기준으로 같냐/틀리냐를 판단한다.
  • 값 같으면 -> 같은 객체를 만족시켜주기 위해서는 같다의 기준을 바꿔줬었다.
    • 같다의 기준메모리 주소 비교 -> 값 비교equals 오버라이딩으로 바꿔줘야했지만,
  • 이번엔 자료구조 등이 받아서 읽을해쉬코드 기준을 객체의 메모리주소정수 반환이 아닌 -> 객체(Car)가 가진 값(name)의 메모리 주소 정수 반환로 바꿔준다.
    • cf) 값의 메모리주소 -> 같은 문자열이면 다 같다

자료구조들도 같은 객체로 인식

쉽게 말해서, 반환되는 hashCode도 값 기준으로 바꿔서, 값 같다 -> 객체의 해쉬코드 같다를 만들어버린다.

  • 그렇지 않으면, equals는 True로 나올지 몰라도, 자료구조는 다른 객체로 인식하는 상태가 된다.
@Test
void before_overriding_hashcode_test() {
    final Car 재성 = new Car("차");
    final Car 석영 = new Car("차");

    final HashSet<Car> set = new HashSet<>();
    set.add(재성);
    set.add(석영);

    assertThat(set.size()).isEqualTo(1);
    //Expected :1
    //Actual   :2
    // hashCode를 객체기준->값기준으로 정의해주지 않으면, 자료구조들은 다른 객체로 인식한다.
}
  • hashCode오버라이딩 후
@Test
void after_overriding_hashcode_test() {
    //2.
    final Car 재성 = new Car("차");
    final Car 석영 = new Car("차");

    final HashSet<Car> set = new HashSet<>();
    set.add(재성);
    set.add(석영);

    assertThat(set.size()).isEqualTo(1); // true
}