Object 메서드와 비교: equals, hashCode, toString, Comparable
모든 클래스가 물려받는
Object의 세 메서드와 정렬 인터페이스 둘을 다룹니다. "내용이 같은 두 객체" 를 자바가 언제 같다고 보는지,HashSet과HashMap이 왜hashCode없이는 동작하지 않는지, 로그에Member@1b6d3586이 찍히는 이유가 무엇인지, 정렬 기준을 클래스 안(Comparable)에 둘지 밖(Comparator)에 둘지를 실행으로 확인합니다. 컬렉션 레슨의 실수 1·2 가 바로 이 레슨의 내용이며, record 가 이 셋을 자동으로 만들어 주는 것이 얼마나 큰 편의인지도 알게 됩니다.
1. 왜 배우는가
List.contains, Set.add, Map.get, remove, indexOf, distinct 는 전부 equals 로 "같은 것" 을 찾습니다. equals 를 정의하지 않은 클래스는 Object.equals 를 물려받는데, 그것은 == 와 같아서 "같은 객체" 만 같다고 봅니다.
DB 에서 읽은 회원과 화면에서 만든 회원은 id 가 같아도 다른 객체이니 contains 가 false 입니다. 이것이 "분명히 넣었는데 없다고 나온다" 의 원인 1순위입니다.
hashCode 는 더 미묘합니다. equals 만 만들고 hashCode 를 빠뜨리면 List 에서는 잘 되다가 HashSet·HashMap 에서만 깨집니다. 테스트에서 List 로 확인하고 운영에서 Map 을 쓰면 그때 터집니다. 둘을 항상 같이 만들어야 하는 규칙에는 명확한 이유가 있고, 컬렉션 레슨의 HashMap 내부 구조를 알면 그 이유가 보입니다.
toString 은 장애 대응의 도구입니다. 로그에 Order@3e25a5 가 찍히면 어느 주문인지 알 수 없습니다. 반대로 비밀번호까지 찍히면 사고입니다.
정렬은 실무 화면의 기본이고, "이름순 다음 날짜 내림차순, null 은 뒤로" 같은 요구를 Comparator 조합 한 줄로 쓰는 것과 if 문 스무 줄로 쓰는 것의 차이가 큽니다. 그리고 TreeSet·TreeMap 은 equals 가 아니라 compareTo 로 중복을 판단하므로 둘이 어긋나면 데이터가 사라집니다.