JAVA

태태개발일지 - equals and hashcode 동시 재정의?

태태코 2024. 12. 5. 11:10
반응형

동등성 & 동일성

자바에서 객체를 비교할 때는 equals() 메서드와 == 연산자를 사용한다.

equals 메서드는 동등성 , == 연산자는 동일성을 의미한다.

 

쉽게 이야기하자면,

equals : 객체의 값을 비교하는 것

==:  객체의 실제 레퍼런스를 비교하여 동일한 객체인지 확인하는 것

 

ex)

Test test = new Test("1");
Test test2 = new Test("1");

 equals 메서드를 재정의한 test1.equals(test2) // true
 test1 = test2 // false

 

이게 무슨 이야기인지 봐보자면,

equals는 값을 비교했기 때문에 동등하다. 그래서 true가 나온것이고,

== 는 객체의 레퍼런스를 비교했기 서로다른 객체이기 때문에   동일하지 않다. 

 

라는 결과가 나오고, 그렇다면 재정의한 메서드? 라는 게 무슨 뜻인가 하면

 

 return (this == obj);

 

재정의 하지 않은 equals는 메서드안에서 동일성을 비교하기 때문에 값만으로는 비교할 수 없어서 객체를 값으로 비교하여 동등성을 판단하고 싶다면 클래스에서 equals() 메서드를 재정의 하여 사용하면 된다.

 

 

   @Override
    public boolean equals(Object obj) {
        if (this == obj) return true; // 같은 객체를 참조하면 true
        if (obj == null || getClass() != obj.getClass()) return false; // 타입 확인
        Test test = (Test) obj; // 비교하려는 객체로 캐스팅
        return id == test.id && Objects.equals(value, test.value); // id와 value 비교
    }

 

아래와 같이 재정의하면된다.

 

 HASHCODE라는 개념이 같이 등장해야한다.

 

hashCode(): 객체를 해시 기반 컬렉션(예: HashMap, HashSet)에서 빠르게 찾을 수 있도록 정수값(해시코드)을 반환.

 

 

HashSet은 내부적으로 hashCode()를 사용해서 객체를 저장하고 관리한다.

  • 객체를 저장할 때:
    1. 먼저 hashCode()로 해시 값을 계산해서 적절한 버킷(bucket)을 찾는다.
    2. 버킷 안에서 equals()로 같은 객체가 있는지 확인한다.

 

 

 

 

그럼 왜 같이 재정이할까? 에 대해서 생각해보면

 

자바의 규약에 따르면, equals()가 true를 반환하는 두 객체는 같은 hashCode() 값을 가져야 한다. 이 규약을 따르지 않으면, 해시 기반 컬렉션이 제대로 동작하지 않는다.

 

 

규약을 안 따르면 발생하는 문제:

  • equals()만 재정의:
    • 두 객체가 논리적으로 같아도 hashCode() 값이 다르면 다른 버킷에 저장된다
  • hashCode()만 재정의:
    • hashCode()는 같지만 equals()가 다르면, 같은 객체로 인식되지 않는다.

 

 

결과적으로 중복된 객체가 허용될 수 있다.

반응형

'JAVA' 카테고리의 다른 글

태태개발일지 - 김영한의 실전 자바 - 고급편  (1) 2025.01.30
태태개발일지 - 레코드  (1) 2024.12.25
태태개발일지 - Exception  (2) 2024.10.14
Java 중급 - 영한쌤  (1) 2024.03.31
태태개발일지(JAVA 상속)  (0) 2024.01.09