- equals와 hashCode는 왜 함께 재정의해야 할까요?2024년 12월 16일 18시 38분 30초에 업로드 된 글입니다.작성자: do_hyuk
equals와 hashCode 메서드는 객체의 동등성 비교와 해시값 생성을 위해서 사용할 수 있습니다. 하지만, 함께 재정의하지 않는다면 예상치 못한 결과를 만들 수 있습니다. 가령, 해시값을 사용하는 자료구조(HashSet, HashMap..)을 사용할 때 문제가 발생할 수 있습니다.
class EqualsHashCodeTest { @Test @DisplayName("equals만 정의하면 HashSet이 제대로 동작하지 않는다.") void test() { // 아래 2개는 같은 구독자 Subscribe subscribe1 = new Subscribe("team.maeilmail@gmail.com", "backend"); Subscribe subscribe2 = new Subscribe("team.maeilmail@gmail.com", "backend"); HashSet<Subscribe> subscribes = new HashSet<>(List.of(subscribe1, subscribe2)); // 결과는 1개여야하는데..? 2개가 나온다. System.out.println(subscribes.size()); } class Subscribe { private final String email; private final String category; public Subscribe(String email, String category) { this.email = email; this.category = category; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Subscribe subscribe = (Subscribe) o; return Objects.equals(email, subscribe.email) && Objects.equals(category, subscribe.category); } } }
왜 이런 현상이 발생하나요? 🤔
해시값을 사용하는 자료구조는 hashCode 메서드의 반환값을 사용하는데요. hashCode 메서드의 반환 값이 일치한 이후 equals 메서드의 반환값 참일 때만 논리적으로 같은 객체라고 판단합니다. 위 예제에서 Subscribe 클래스는 hashCode 메서드를 재정의하지 않았기 때문에 Object 클래스의 기본 hashCode 메서드를 사용합니다. Object 클래스의 기본 hashCode 메서드는 객체의 고유한 주소를 사용하기 때문에 객체마다 다른 값을 반환합니다. 따라서 2개의 Subscribe 객체는 다른 객체로 판단되었고 HashSet에서 중복 처리가 되지 않았습니다.
'면접 대비' 카테고리의 다른 글
@Component, @Controller, @Service, @Repository의 차이에 대해서 설명해주세요. (0) 2024.12.18 동일성과 동등성에 대해서 설명해주세요. (0) 2024.12.17 JPA에서 ID 생성 전략에 대해 설명해주세요. (1) 2024.11.29 로그와 메트릭을 설명해주세요. (0) 2024.11.28 얕은 복사와 깊은 복사에 대해서 설명해주세요. (0) 2024.11.27 댓글