728x90
반응형
Set과 Map의 타입이 Wrapper Class가 아닌 Object를 받을 때 중복 검사는 어떻게 진행하는가?
➕ hashCode() 메서드를 오버라이딩하여 리턴된 해시코드 값이 같은지 판단합니다. 값이 다르다면 다른 객체로 판단하고, 해시코드 값이 같다면 equals()메서드를 오버라이딩 하여 다시 비교합니다.
위의 개념을 위해서는 동일성과 동등성을 먼저 알아야한다.
**동일성** : 두 개의 객체가 완전히 하나의 같은 객체인지 판단하는 것. 즉 , 메모리에 저장된 주소공간이 완전히 같을 경우 동일성이 보장된다.
**동등성** : 두 객체의 주소공간이 달라도 단순히 가지고 있는 값만 같다면 동등성이 보장된다.
이는 단순 문자열(원시형)과 객체로 생성한 값 사이의 차이점과 동일하다.
그 다음으로는 equals의 필요성이다. equals가 필요한 이유는 객체지향의 캡슐화 개념때문이기도 하다. 내부 사앹 정보를 숨긴 채로 두 객체의 동등성 정보를 파악해야 하는데, 따라서 상태 간 비교가 아닌 더 큰 개념에서 객체와 객체 사이의 정보를 비교해야 한다. 그러므로 equals의 오버라이딩이 필요하다.
- 예시코드(equals 그대로 사용)
- 내부 상태가 완전히 같아도 동등성을 보장할 수 없다.
public static void main(String[] args) { Car car1 = new Car(1,"sonata"); Car car2 = new Car(1,"sonata"); System.out.println(car1.equals(car2)); //false }
- 예시코드(equals를 재정의)
- 동등성이 보장된다.
public class Car { private final int id; private final String name; public Car(int id, String name) { this.id = id; this.name = name; } @Override public boolean equals(Object o) { if (this == o) { return true; } if (o == null || getClass() != o.getClass()) { return false; } Car car = (Car) o; if (id != car.id) { return false; } return Objects.equals(name, car.name); } } public static void main(String[] args) { Car car1 = new Car(1,"sonata"); Car car2 = new Car(1,"sonata"); System.out.println(car1.equals(car2)); //true }
마지막으로 가장 중요한 hashcode는 왜 필요한가이다. equals만 잘 재정의하면 모든 객체의 동등성이 보장될 것 같지만 그렇지 않다. Hash값을 사용하는 Hash Collection 자료구조(HashMap, HashSet, HashTable)때문에 발생한다.
- 예시코드
- Set을 사용하여 완전히 상태가 같은 객체를 두 번 넣어지만 길이가 1이아닌 2가 나온다.
- 동등성 보장에 실패한 것이다.
- 원인은 아래의 사진과 같다.
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임 }
보장되지 않는 이유
- Hash를 사용하는 Collection들은 객체의 동등성 비교를 다음 고정과 같이 수행한다.
- 일단 hashcode값이 서로 같아야만 equals메소드로 객체비교를 수행한다.
- hashcode와 equals를 모두 재정의 해줘야 객체의 동등성이 비교된다.
728x90
반응형
'JAVA-기초 > JAVA기본' 카테고리의 다른 글
[Java- Algorithm] 너비 우선 탐색법(BFS과 큐(Queue) (0) | 2024.02.28 |
---|---|
[자료구조 - Graph 와 DFS] Graph와 DFS란? (0) | 2024.02.24 |
자바(java) - Optional이란? (2) | 2023.12.06 |
[Java] 객체지향개념(OOP) 캡슐화와 정보은닉 (3) | 2023.09.03 |
객체지향 프로그래밍 5가지 설계 원칙, SOLID- 단일책임의 원칙 (64) | 2023.08.12 |