Java에서는 객체를 정렬하기 위해 2가지의 인터페이스를 제공합니다.
1. Comparable
2. Comparator
알고리즘을 공부하다 보면 정렬 문제를 자주 보게 되는데, 이것과 관련해 Comparable과 Comparator를 각각 알아보고 차이를 살펴보도록 하겠습니다.
시작하기 전에 알아야할 것은 Comparable과 Comparator는 모두 인터페이스(interface)
라는 것입니다. 인터페이스를 사용하기 위해서는 인터페이스 내에 선언된 메소드를 반드시 구현해야 합니다.
*공식 API 문서 [Comparable, Comparator]
https://docs.oracle.com/javase/8/docs/api/java/lang/Comparable.html#method.summary
Comparable (Java Platform SE 8 )
This interface imposes a total ordering on the objects of each class that implements it. This ordering is referred to as the class's natural ordering, and the class's compareTo method is referred to as its natural comparison method. Lists (and arrays) of o
docs.oracle.com
http://docs.oracle.com/javase/8/docs/api/java/util/Comparator.html#method.summary
Comparator (Java Platform SE 8 )
Compares its two arguments for order. Returns a negative integer, zero, or a positive integer as the first argument is less than, equal to, or greater than the second. In the foregoing description, the notation sgn(expression) designates the mathematical s
docs.oracle.com
Comparable의 경우 compareTo(T o) 메소드 하나가 선언되어있는데 사용자가 이 인터페이스를 사용하려면 이 메소드를 구현(Override)해주어야 합니다. Comparator도 마찬가지로 compare(T o1 T o2) 메소드를 Override 하면 됩니다. (다른 메소드도 많지만 두 매개변수를 비교하는 compare 메소드를 예로 들었습니다.)
두 인터페이스는 흔히 객체를 정렬한다고 설명합니다. 그렇다면 객체는 무엇을 기준으로, 어떻게 비교하여 정렬하는 걸까요?
만약 변수가 원시 타입(primitive type)이라면 (ex. int, double, float 등) 값은 부등호를 통해 쉽게 비교할 수 있습니다. 하지만 우리가 클래스 객체를 만들어서 비교를 한다고 하면? 예를 들어 객체가 Book 이고 책 번호와 가격 정보를 가지고 있을때 이 객체를 정렬하기 위해서는 번호를 기준으로 할 것인지 가격을 기준으로 할 것인지 정해줄 필요가 있습니다. 객체 자신은 어떤 객체가 우선순위를 가지는지 알 수 없기 때문이죠.
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class Main {
public static void main(String[] args) {
List<Book> books = new ArrayList<>();
books.add(new Book(101, 29.99));
books.add(new Book(103, 19.99));
books.add(new Book(102, 39.99));
// 이제 books 리스트 안에 책들을 어떤 기준으로 정렬하지?
}
}
그렇기 때문에 객체를 비교할 수 있게 정렬 기준을 Comparable 과 Comparator 인터페이스를 사용하여 우리가 직접 구현해야 합니다.
그러면 Comparable, Comparator의 차이는 무엇일까요? 가장 먼저 보이는 것은 메소드의 매개변수의 차이인데요. Comparable의 compareTo( ) 메소드는 매개변수가 하나이고 Comparator의 compare( ) 메소드는 매개변수가 두개입니다.
정답은 Comparable은 "자기 자신과 매개변수 객체를 비교"하는 것이고, Comparator는 "두 매개변수 객체를 비교"한다는 것입니다.
두 메소드를 구현해보면서 살펴보겠습니다.
* compareTo(T o) 메소드
자기 자신의 price 와 매개변수로 들어온 Book 객체의 price를 비교할 수 있다. (자기 자신을 기준으로 대소관계를 파악)
public int compareTo(Book o){
// 자기자신의 price가 o의 price보다 크다면 양수
if(this.price > o.price) {
return 1;
}
// 자기 자신의 price와 o의 price가 같다면 0
else if(this.price == o.price) {
return 0;
}
// 자기 자신의 price가 o의 price보다 작다면 음수
else {
return -1;
}
}
* compare(T o1 T o2) 메소드
자기 자신이 아닌 파라미터(매개 변수)로 들어오는 두 객체를 비교한다. (자기 자신과는 상관 없이 매개변수로 넘겨진 두 객체만 비교)
public int compare(Book o1, Book o2) {
// o1의 bookNumber가 o2의 bookNumber보다 크다면 양수
if(o1.bookNumber > o2.bookNumber) {
return 1;
}
// o1의 bookNumber가 o2의 bookNumber와 같다면 0
else if(o1.bookNumber == o2.bookNumber) {
return 0;
}
// o1의 bookNumber가 o2의 bookNumber보다 작다면 음수
else {
return -1;
}
}
만약 a.compare 메소드에서 a와 비교하고 싶다면 a.compare(a, b) 를 해주면 된다.
'Java' 카테고리의 다른 글
[Java] 싱글톤(Singleton) 패턴 + 스프링의 싱글톤 (0) | 2024.07.22 |
---|---|
[Java] Stream(스트림) 정리하기 + Stream 활용 예제 (1) | 2024.07.08 |
[Java] Hash란? - HashSet, HashMap 특징과 구현 (0) | 2024.07.01 |