동일성 vs 동등성
동일성은 두 객체의 주소가 같은 것을 말한다.
반면
동등성은 두 객체의 주소와 내용이 같은 것을 말한다.
equals()와 hashCode()
equals()는 모든 객체의 부모인 Object 클래스의 메소드로 모든 객체들이 상속받는다.
Object에 정의된 equals()는 객체의 주소값만을 통해 동일성을 판단한다.
hashCode()도 마찬가지로 Object클래스의 메소드로 모든 객체들이 상속받는다.
Object에 정의된 hashCode()는 객체의 고유값인 해시값을 반환한다.
하지만 여기서 주의해야할 점은 다른 객체라고 해서 무조건 해시값이 같은 건 아니다.
다음의 예시를 보자.
String s1 = new String("s");
String s2 = new String("s");
System.out.println(s1.hashCode());
System.out.println(s2.hashCode());
System.out.println(s1 == s2);
출력
- s1과 s2는 다른 객체이지만 해시값이 같다.(문자열은 내용이 같다면 같은 해시값을 반환)
이렇듯 주소값이 달라도 해시값은 다를 수 있다. 이를 해시 충돌이라고 한다.(Hash Collision)
해시기반 컬렉션의 동등성 비교(equals(), hashCode())
HashSet, HashMap등의 컬렉션에서 특정 객체의 필드를 통해 중복을 체크하고 싶을 때, equals()뿐만 아니라 hashCode()까지 오버라이드한다.
그 방법은 아래 링크 참고
[Java] HashSet - 객체의 속성으로 중복 체크
HashSet의 특징HashSet은 중복을 빠르게 체크할 수 있는 자료구조이다.기존의 List에서 중복여부를 체크하려면 List의 모든 요소를 순회하며 해당 값이 있는지 체크(O(n))해야 했지만HashSet은 그러한 과
jaehee1007.tistory.com
equals()는 앞서 말했듯 주소값 비교 즉, 동일성만을 제공하기 때문에 오버라이드해서 내용비교까지 해줘야 한다.
그렇게 equals()만 오버라이드하면 얼추 중복체크가 될 것 같은데 왜 hashCode()까지 작성해야 할까?
우선 해시기반의 컬렉션이 동등성을 체크하는 순서는 다음과 같다.
우선 hashCode()로 해시코드값을 비교하고 추가적으로 equals()까지해 객체의 주소와 내용까지 확인해 객체의 동등성을 체크한다.
이렇게 이중 체크를 하는 이유는 바로 다른 객체여도 해시값은 다른 경우 즉, 해시 충돌(Hash Collision)이 발생할 수 있기 때문이다.
해시기반의 컬렉션들은 해시함수를 통해 버켓에 데이터를 저장하기 때문에 매우 빠르게 데이터에 접근한다. 하지만 해시 충돌이 발생할 수 있다는 점이 단점이었다. 그러한 단점으로 인해 이렇게 추가적인 과정이 수행되는 것이다.
'Java' 카테고리의 다른 글
[Java] TCP UDP 프로그래밍 (0) | 2024.07.28 |
---|---|
[Java] 스레드(Thread) (0) | 2024.07.27 |
[Java] Stream API (0) | 2024.07.25 |
[Java] 람다식의 이해 (0) | 2024.07.25 |
[Java] HashMap - value값을 기준으로 정렬 (0) | 2024.07.23 |