동일성vs동등성(equals, hashCode)
동일성(메모리주소,==,옵라전equals)과 동등성(값,후equals)
📜 제목으로 보기
동일(ㅣ)성 = (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
}