java에는 equals랑 compareTo가 있습니다. 이 둘을 언제 쓰는지, 차이점을 간단하게 알아보겠습니다.

 


 먼저  compareTo는 비교를 하기 위해 쓰입니다. 순서를 정하기 위해서. 뒤에 for order가 붙은 것을 보면 알 수 있습니다. 당연하게도, comparator의 compare도 같은 용도로 쓰입니다. Compares object for order. 위에서 말한 순서는 무엇일까요? 랭킹을 정한다고 생각해 봅시다.

 

 이름과 점수로 이루어진 object가 있습니다. 우리는 점수별로 순서를 정하려고 합니다.

 

 

 Obj 클래스는 이 상황에서 학생에 대한 데이터를 저장할 거에요. score와 name이 있는데요. 각각 받은 점수와 이름을 저장하고 있습니다. compareTo는 아래와 같이 오버라이딩을 하면 될 거에요.

 

 해당 학생의 score와 다른 학생의 score를 비교했을 때, 해당 학생이 더 점수가 크다면 음수 값을 리턴해서 앞의 순서에 오게 한다.

 

 이제 TreeMap에 점수가 5이고 이름이 A인 사람, 점수가 3이고 이름이 B인 사람, 점수가 2이고 이름이 C인 사람을 넣어 보겠습니다.

 

 

 그러면, 점수가 5인 학생이 가장 앞에 왔음을 볼 수 있어요.

 

 

 즉, score가 5인 사람과 3인 사람을 비교했을 때, 순서를 정하는 기준을 compareTo로 하는 것입니다. 노란색 객체가 파란색 객체보다 order가 앞에 와야 한다면 음수 값을, 뒤에 와야 한다면 0보다 큰 값을 돌려주면 됩니다. 만약에 같으면? 0을 리턴하면 됩니다. 

 

 

 이름이 A인 학생과 B인 학생, 그리고 C인 학생이 있어요. 점수가 모두 같으므로, 이들 각각은 compareTo의 리턴 값이 0입니다.

 

 굳이 그림으로 그리자면 이런 상황입니다. 고로 stable sort가 아니라면, 이 셋은 어떤 순서로 와도 상관이 없게 되어 버립니다만, 오브젝트의 list는 tim sort를 씁니다.

 

 순서는 유지됩니다. 어찌 되었던 순서를 정하는 기준을 compareTo를 오버라이딩 할 수 있어요. compareTo가 0이라는 의미는, 앞에 오나 뒤에 오나 별 상관이 없다. 정도로 해석해도 됩니다. 정렬하는 경우, stable sort인 경우 들어온 순서대로, unstable인 경우 rank가 같으면 아무렇게나 정렬될 겁니다.

 

 


 여기서 질문. a.compareTo(b), 혹은 comparator.compare(a, b)의 리턴값이 0이기 때문에 두 객체는 논리적으로 동등할까요? 물론 완전히 같은 객체를 비교한다면 0이 나올 순 있습니다. 그런데 위에서도 보았다 시피 동점자가 여러 명 있는 경우, 각각의 학생들은 동등하다고 볼 수 없습니다.

 

 

 단지, 5점을 맞은 학생들과 4점을 맞은 학생들의 순서를 정하기 위해 compareTo와 같은 것을 쓴 것 뿐이였습니다. 다시 말하지만 순서를 정하는 기준이 점수라고 합시다. 두 객체를 compare로 비교했을 때 0이 나왔다는 의미는, 동점자였다는 의미입니다. 비교한 결과가 0이라고 해도, 같은 학생이 아닐 수도 있습니다.

 

 만약에 학교에 같은 이름을 가진 둘 이상의 학생이 없다고 해 보겠습니다. 그러면, 이름이 같으면 같은 학생이고, 그렇지 않으면 다른 학생이라고 할 수 있겠습니다.

 

 

 그렇다면, equals를 위와 같이 override 할 수 있습니다. 단순히 name만 같으면 같은 학생이다. 라고 판별해 버리면 됩니다.

 

 학생 s1에 대한 데이터가 있습니다. 점수가 5이고, 이름이 "A"라는군요. 학생 s2는 점수가 5이고, 이름이 "B"입니다. 이 둘을 비교했을 때에는 0이 나옵니다. 그런데, 같은 학생은 아닙니다. 왜? 이름이 다르기 때문입니다. 단지, 동점자여서 비교 함수의 리턴 결과가 0이 나왔을 뿐입니다.

 

 s1과 s3은 어떤가요? 이름까지 같습니다. equals에서 이름이 같으면 동일한 학생으로 본다고 했습니다. 고로 3번째는 true가 나옵니다.

 

 쉽게 정리하면, 순위를 정하기 위해 기준을 정하는 함수가 compareTo와 compare 같은 비교 함수입니다. 두 객체를 이 메서드들로 비교했을 때 0이 나왔다고 논리적으로 동일한 객체가 아닙니다. 왜? 동점자 (동순위 사람)이 있을 수 있기 때문입니다. 논리적으로 같은지를 판정하는 함수가 equals라고 할 수 있겠습니다.