Java - Comparable vs Comparator

728x90

Stream 성애자인 나는 오늘도 코딩 테스트 문제나 비즈니스 로직을 짜면서 Stream을 쓰고있다. 하지만 코딩 테스트를 풀면서 생긴 의문점이 있다. 

바로 정렬을 해주는 sorted() 라는 함수인데 이 안의 파라미터로 Comparator 타입이 들어간다는 갓텔리제이의 TMI한 설명이 있다. 중요한건 이 문제를 이렇게도 풀 수 있지만, 아래와 같이 Music 클래스가 Comparable 인터페이스를 구현하고, compareTo 메서드를 재정의 함으로써도 해결할 수 있다. 

sorted 함수의 파라미터를 Music의 comparTo 메서드로 변경하였다. 
(조금 거슬리는 부분은 compareTo 메서드를 임의로 역순으로 정렬되게 설정하였다는 것이다)

여전히 파란불이 떳다! 

둘다 돼네~ 하고 넘어가자고 하니, 참된 개발자가 아닌 것 같다는 생각과 함께 자괴감에 빠질 것 같아. 이참에 가려운 곳을 긁어보기로 했다. 

1. Interface Comparable

정의 :

정렬 수행 시 기본적으로 적용되는 정렬 기준이 되는 메서드를 정의하는 인터페이스이다. java.lang.Comparable package에 위치한다. 
java에서 제공되는 정렬이 가능한 클래스들은 모두 Comparable 인터페이스를 구현하고 있으며, 정렬 시에 이에 맞게 정렬이 수행된다. 
(ex. 숫자형 (오름차순 정렬): Integer, Doble, Long ...., 문자열 (사전순 정렬) : String )

구현 방법 : 

정렬할 객체에 Comparable interfacefmf implements하고, compareTo() 메서드를 오버라이드 한다! 

더보기

💡 CompareTo() 메서드 작성법
∙ 현재 객체 < 파라미터로 넘어온 객체 : 음수 리턴
∙ 현재 객체 == 파라미터로 넘어온 객체 : 0 리턴 
∙ 현재 객체 > 파라미터로 넘어온 객체 : 양수 리턴 
∙ 음수 또는 0 이면 객체의 자리가 그대로 유지되며, 양수인 경우에는 두 객체의 자리가 바뀐다.

아래는 Integer의 compareTo() 메서드다 (Integer class는 Comparble을 

 

사용 방법 : 

∙Arrays.sort(array)
∙Collections.sort(this) 

더보기

참고 : Arrays.sort()와 Collections.sort()의 차이

1. Arrays.sort() 
배열을 정렬할 때 사용
∙ex) byte[], char[], double[], int[], Object[], T[] etc... 등 Object Array에서는 TimSort(병합 정렬 + 삽입 정렬)를 사용
∙Object Array: 새로 정의한 클래스에 대한 배열 * Primitive Array에서는 Dual Pivot QuickSort(퀵 정렬 + 삽입 정렬)를 사용 
∙Primitive Array: 기본 자료형에 대한 배열

2. Collectrions.sort()
List Collection을 정렬할 때 사용
∙Ex) ArrayList, LinkedList, Vector etc.. * 내부적으로 Arrays.sort()를 사용

 

2. Interface Comparator 

정의 :

  • 정렬 가능한 클래스(Comparable 인터페스를 구현한 클래스)들의 기본 정렬 기준과 다르게 정렬하고 싶을 때 사용하는 인터페이스
  • java.util.Comparator package에 위치한다.
  • 주로 익명 클래스로 사용된다. 
  • 기본적인 정렬 방법인 오름차순 정렬을 내림차순으로 정렬할 때 많이 사용한다.

구현 방법 :

  • Comparator interface를 implements gn compare() 메서드를 오버라이드 한 myComparator class를 작성한다. 
  • compare() 메서드 작성 법 (오름 차순의 경우 Comparable의 compareTo() 메서드 구현과 동일 하고, 내림 차순의 경우 두 대소 비교를 반전시키면 된다) 

사용 방법 : 

  • Arrays.sort(array, Comparator);
  • Collections.sort(list, Comparator);
  • Arrays.sort(), Collections.sort() 메서드는 두 번째 인자로 Comparator interface를 받을 수 있다. 

Comparator interface를 이용한 Java 객체 정렬 방식은 두 가지가 있다. 

먼저 첫 번째로는 class T가 Comparator<T>를 구현하게 만들고 compare() 메서드를 오버라이드 하면 된다. 이는 위의 Comparable을 구현하는 것가 거의 유사하기 때문에 생략한다. 

두 번째는 처음에도 언급했듯이, 익명 함수를 이용하는 것이다.

new Comparator<Music> 부분이 비활성화(?) 되어있다. 그 이유는 익명 클래스를 intelligent(= 총명한, 똑똑한)한 갓텔리제이는 람다식으로도 바로 바꿔줄 수 있기 때문이다. (사실, 처음부터 람다식으로 코드를 짯지만, IntelliJ의 quick function 기능으로 lambda 식을 abstract class로 변환하여 익명 클래스로 변경하였다. 보는 것 처럼 익명 클래스는 가독성이 매우 떨어진다. 가독성 적인 측면에서 익명 클래스보다는 람다식을 활용하자!) 

이번 포스팅을 하면서 Comparable과 Comparator의 개념에 대해서 알아보았다. 정리하면서 이제 좀 명확해지는 것 같다. 
간단하게 말하자면 Comparable은 기본적인 정렬할 때 사용, Comparator은 기본 정렬 기준과 다른 정렬을 정의할 때 사용!

참조: https://gmlwjd9405.github.io/2018/09/06/java-comparable-and-comparator.html

 

[Java] Comparable와 Comparator의 차이와 사용법 - Heee's Development Blog

Step by step goes a long way.

gmlwjd9405.github.io

 

728x90