📝느낀 점
우테코 프리코스 할때가 생각난다. 한주 과제를 제출하고 나면 다른 사람들은 어떤 식으로 코드를 작성하였나? 궁금하고, 배우고 싶기에 여러 사람들의 코드를 봤던 기억이 난다. 그때 어떤 사람들은 equals, hashCode 이런 메서드들을 정의하고 사용하고 있었는데, "저게 뭘까?" 하며 구글링을 하며 찾아보며 했지만, equals, hashCode라는 것에 개념만 알게 되었다
그 뒤로 시간이 지나 자바에 대해 깊게 공부해보자는 생각에 이렇게 정리를 해본다. equals는 주소값이 달라도 문자에 대한 내용만 같다면 같다고 보는 메서드이고, hashCode은 해시 컬렉션에서 사용되며, 동일한 객체라면 동일한 해시코드를 가지고 있기에, hashCode 메서드도 같이 재정의하여 사용하게 되는 개념인것 같다.
먼저 equals는
equals는 같은 타입의 두 참조 변수가 같은지 비교할 때 사용한다. 그리고 동등성의 개념이다.
동등성이란? 변수가 참조하고 있는 객체의 주소가 서로 다르더라도 내용만 같으면
두 변수는 동등하다고 이야기할 수 있다.
그렇다면, 동일성이란?
말 그대로 객체 A와 객체 B가 완전히 같은 하나의 객체라는 것이다.
즉, 메모리에 저장된 주소 공간이 완전히 같을 경우, "객체 A와 B는 동일하다" 라고 표현 한다.
Primitive 타입은 객체가 아니라 주소가 없으므로
'==' 연산자를 사용하였을 때 내용이 같으면 동일하다고 말한다.
코드로 확인해보기
class Main {
public static void main(String[] args) {
String person1 = new String("seok");
String person2 = new String("seok");
System.out.println(person1 == person2); //false
System.out.println(person1.equals(person2)); //true
}
}
위 코드 처럼 new String을 통해 참조 타입으로 변수를 생성한 경우, 참조 타입은 주소 공간을 저장하므로,
주소 공간이 다른, person1과 person2는 동일성이 보장되지 않고 동등성만 보장 된다.
equals를 구현하지 않을 경우 -> false!!
public static void main(String[] args) {
Car car1 = new Car(1,"avante");
Car car2 = new Car(1,"avante");
System.out.println(car1.equals(car2)); //false
}
hashcode()
비교 하는 객체의 유일한 integer값을 반환한다는 것이다. (동일한 객체는 동일한 해시코드를 가져야 한다.)
해시코드는 해시 테이블과 같은 자료 구조에서 객체를 빠르게 검색하기 위해 사용되며,
동등성 보장 실패에 대한 이유도 있다.
그리고 hashcode가 필요한 이유는?
equals만 잘 재정의 하면 모든 객체의 동등성이 보장될 것 같지만, 모든 객체가 그렇지는 않다는 것이다.
이, 예외는 Hash 값을 사용하는 Hash Collection들인 자료구조(HashMap, HashSet, HashTable) 때문에 일어난다.
public static void main(String[] args) {
Set<Car> cars = new HashSet<>();
cars.add(new Car(1, "sonata"));
cars.add(new Car(1, "sonata"));
System.out.println(cars.size()); // 2 -> HashSet 사이즈가 1이 아닌 2임
}
중복을 불허 하는 Set을 사용하여 완전히 상태가 같은 객체를 두 번 set에 집어넣었다.
이론 상으로는 중복이기에 Hashset의 길이가 1이어야 하지만 프로그램을 돌리면 길이가 2가 나온다는 것이다.
동등성 보장에 실패한 것이다.
equals, hashCode 동작 원리
출처 : https://tecoble.techcourse.co.kr/post/2020-07-29-equals-and-hashCode/
즉, hashcode값이 서로 같아야만 equals 메소드로 객체 비교를 수행하는 것이다.
Hashcode가 다르면 동등성 비교는 쳐다 보지도 않는다는 말입니다.
정리
equals 메서드를 재정의한 경우, hashCode 메서드도 재정의하여 일관성 있게 동작하도록 해야 한다.
이렇게 하지 않으면 같은 내용을 가진 객체라도 서로 다른 해시 코드를 반환할 수 있어,
해시 테이블 등에서 문제가 발생할 수 있다.
Reference
'Java' 카테고리의 다른 글
exception VS error 차이가 무엇인가요? (0) | 2023.11.07 |
---|---|
불변 객체나 final을 굳이 사용해야 하는 이유가 있나요? (0) | 2023.11.07 |
static에 대해 설명 / static을 사용하는 이유는? (0) | 2023.11.07 |
enum 사용하는 이유는 무엇인가요? (0) | 2023.11.07 |
제네릭이 필요한 이유는 무엇인가요? (0) | 2023.11.06 |