본문 바로가기
java

compareTo()를 재정의 시 equals()를 왜 함께 재정의 해야할까?

by 참된오징어 2021. 1. 25.

해당 글을 작성하게 된 이유는 NEXT STEP에서 클린 코드 과정 리뷰어로 활동하면서

가끔 중복으로 드리는 내용 중 하나이며 compareTo를 재정의 시 equals()를  함께 재정의 하는걸 권장하는지

포스팅하면 좋을 것 같아 작성하게 되었다.

 

주로 작성하는 피드백 내용은 다음과 같다.

 

위의 리뷰 내용을 확인해보면 compareTo 메서드를 재정의 시 equals() 메서드를 재정의하는 것을 강하게 권장하는 내용이다.

강하게 권장하는 이유를 우선순위 큐를 예로 들어 설명하고자 포스팅을 작성하게 되었다.

 

예로 버전 별 우선순위 큐의 remove() 메서드에서 내부 차이가 존재한다.

(HashSet, TreeSet과 같은 컬렉션은 대표적인 예이기에 생략하고 우선순위 큐만 포스팅 하였다.)

 

실제로 버전별 어떤 차이가 존재하는지 살펴보자.

 

 

 

JDK 1.8  

javadoc 1.8에서의 설명은 다음과 같다. 
docs.oracle.com/javase/8/docs/api/

 

큐에 하나 이상의 해당 요소가 포함되어 있는 경우 요소 제거 시 eqauls를 통해 삭제한다.라는 내용을 확인할 수 있다.

doc도 확인했으니 직접 코드 내부도 확인해보자!

 

 

1.8 우선순위 큐 remove()

1.8 기준으로 우선순위 큐의 내부 remove 구현은 다음과 같다.

삭제하려는 요소를 파라미터로 전달받아 indexOf() 메서드를 통해 index를 얻어온다는 것을 확인할 수 있다.

indexOf 내부 구현을 살펴보자!

 

 

 

1.8 우선순위 큐 indexOf()

내부 구현을 보면 depth 3번째에 eqauls를 통해 값이 같은지 확인하고 있다..!

즉, 1.8에서 compareTo 대신 equals를 통해 값을 확인하고 있다는 것을 확인할 수 있다! 

 

 

 

JDK 1.5

javadoc 1.5에서의 설명은 다음과 같다. 
docs.oracle.com/javase/1.5.0/docs/api/

1.8과 다르게 equals 가 언급되어 있지 않다..! 1.8과 같이 1.5 내부 구현을 살펴보자!

 

1.5 우선순위 큐 remove()

 

remove() 내부 구현은 equals()가 아닌 compareTo()로 비교하며 요소를 삭제함을 확인할 수 있다!

 


위에서 compareTo를 재정의 시 equals를 같이 재정의해야 하는 이유를 java doc과 내부 코드를 살펴보면서 확인하였다.

 

누구나 작성하는 코드는 레거시 코드가 될 수 있다. (자바의 아버지 제임스 고슬링이 작성한 코드도 레거시가 될 수 있다..!)

 

위에서 설명된 내용 또한 레거시 코드가 탄생되고 리팩토링의 과정에서 발생된 차이점이 아닐까 싶다.

 

극단적으로 현재 사용하고 있는 버전도 구현된 코드도 언제 바뀔지 모른다.

 

사소하지만 차이점을 알고 사용한다면 변화에 언제든지 대응할 수 있다고 생각한다.

 

 

 

댓글