목적
Comparator과 Comparable의 뜻은 각각 '비교기', '비교할 수 있는' 이다.
Java에서는 이 두 가지가 인터페이스로 정의되어 있다.
이 두 인터페이스 Comparator과 Comparable은 배열이나 List들을 정렬할 때,
정렬의 기준을 쉽게 커스터마이징할 수 있도록 도와주는 인터페이스이다.
두 인터페이스를 활용할 때 어떠한 차이점이 있는지와 활용 방법에 대해 알아보고자 한다.
Comparator
먼저 Comparator 인터페이스에 대해 알아보고자 한다.
Comparator 인터페이스는 자바에서 제공하는 인터페이스 중 하나로, 객체들의 정렬에 사용되는 메소드를 정의한다.
이 인터페이스를 구현함으로써 사용자가 원하는 방식으로 객체를 비교하고 정렬할 수 있다.
public interface Comparator<T> {
int compare(T obj1, T obj2);
}
compare() 메서드가 포함되어 있어
해당 메서드를 구현하여 원하는 비교 로직을 작성하면된다.
두 개의 매개변수로 비교 대상 객체(obj1, obj2)을 받으며, int 값을 반환합니다. 반환 값은 다음과 같다.
- 0: obj1과 obj2가 동일한 순서입니다.
- 양수: obj1이 obj2보다 큰 순서입니다.
- 음수: obj1이 obhj2보다 작은 순서입니다.
Comparator로 List 정렬하기
Comparator를 이용하여 List를 적용하려면
아래의 Collections 클래스에 있는 sort(List<T> list, Comparator<? super T> c) 를 이용하여
정렬을 할 List와 Comparator 인터페이스를 직접 구현한 클래스를 매개변수로 넘겨주면 된다.
public static <T> void sort(List<T> list, Comparator<? super T> c) {
list.sort(c);
}
사용예시
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
class Person {
private String name;
public Person(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
class NameComparator implements Comparator<Person> {
public int compare(Person person1, Person person2) {
return person1.getName().compareTo(person2.getName());
}
}
public class Main {
public static void main(String[] args) {
List<Person> people = new ArrayList<>();
people.add(new Person("Alice"));
people.add(new Person("Bob"));
people.add(new Person("Charlie"));
Collections.sort(people, new NameComparator());
for (Person person : people) {
System.out.println(person.getName());
}
}
}
Comparator로 배열 정렬하기
배열 역시 아래의 Arrays클래스에 있는 sort(T[] a, Comparator<? super T> c) 메서드를 사용하여 정렬할 수 있다.
public static <T> void sort(T[] a, Comparator<? super T> c) {
if (c == null) {
sort(a);
} else {
if (LegacyMergeSort.userRequested)
legacyMergeSort(a, c);
else
TimSort.sort(a, 0, a.length, c, null, 0, 0);
}
}
사용예시
import java.util.Arrays;
import java.util.Comparator;
public class ArraySortingExample {
public static void main(String[] args) {
// 문자열 배열 생성
String[] fruits = {"apple", "banana", "orange", "grape"};
// 알파벳 순으로 배열 정렬 (오름차순)
Arrays.sort(fruits);
System.out.println("알파벳 오름차순: " + Arrays.toString(fruits));
// 길이 기준으로 내림차순으로 배열 재정렬
Arrays.sort(fruits, new LengthComparator());
System.out.println("길이 내림차순: " + Arrays.toString(fruits));
}
}
class LengthComparator implements Comparator<String> {
@Override
public int compare(String s1, String s2) {
return Integer.compare(s2.length(), s1.length()); // 길이를 비교하여 내림차순으로 정렬
}
}
익명 클래스 활용하기
Arrays.sort(arr, new Comparator<T>(){ public int compare(T o1, T o2) { // 정렬 로직 } });
일회성으로 끝날 정렬 로직이라면 따로 구현할 필요없이 위 처럼 익명 클래스를 활용하여 작성해도 된다.
혹시 Comparator을 쓰지않고도 Arrays.sort()를 사용한 적이 있으신가요?
그것이 가능했던 이유는 정렬을 해주어야하는 클래스가 내부적으로 아래의 Comparable가 구현되었기 때문입니다.
Comparable
Comparable 인터페이스를 구현한 클래스 객체들로 이루어진 배열 또는 List 정렬하고 싶다면,
해당 클래스는 compareTo() 메서드를 재정의(override)해야한다.
즉, 정렬하고자 하는 클래스가 반드시 Comparable 인터페이스를 구현해야 한다.
public interface Comparable<T> {
public int compareTo(T o);
}
compareTo() 메서드는 두 개의 객체를 비교하여 순서를 결정하는 로직을 작성해야 한다.
- 0: this(=새로 들어온 값)와 o는 동일한 순서입니다.
- 양수: this(=새로 들어온 값)이 o보다 큰 순서입니다.( = 순서를 바꾸지 않습니다.)
- 음수: o가 this(=새로 들어온 값)보다 큰 순서입니다. ( = 순서를 바꿉니다.)
Comparable 로 List 정렬하기
사용예제
class Person implements Comparable<Person> {
private String name;
public Person(String name) {
this.name = name;
}
public int compareTo(Person otherPerson) {
return this.name.compareTo(otherPerson.getName());
}
}
List<Person> people = new ArrayList<>();
people.add(new Person("Alice"));
people.add(new Person("Bob"));
people.add(new Person("Charlie"));
Collections.sort(people);
for (Person person : people) {
System.out.println(person.getName());
}
정렬할 클래스에 compareTo()를 구현하고 Collections.sort()로 정렬하는 것을 확인
Comparable 로 배열 정렬하기
사용예제
class Person implements Comparable<Person> {
private String name;
public Person(String name) {
this.name = name;
}
public int compareTo(Person otherPerson) {
return this.name.compareTo(otherPerson.name);
}
}
Person[] people = new Person[3];
people[0] = new Person("Alice");
people[1] = new Person("Bob");
people[2] = new Person("Charlie");
Arrays.sort(people);
for (Person person : people) {
System.out.println(person.getName());
}
정렬할 클래스에 compareTo()를 구현하고 Arrays.sort()로 정렬하는 것을 확인
요약
1. Comparator, Comparable 인터페이스는 정렬 커스터마이징을 쉽게 작업할 수 있도록 도와주는 인터페이스다.
2. 재정의 메소드
- Comparator는 compare()메소드를
- Comparable은 compareTo() 메소드를
재정의 해야 한다.
3. Comparator, Comparable 인터페이스를 재정의 하여 정렬을 할 때,
- List는 Collections.sort()함수를
- 배열은 Arrays.sort() 함수를
사용하면 된다.
'language > JAVA' 카테고리의 다른 글
[JAVA] 배열, 스트림 활용 (0) | 2024.06.22 |
---|---|
[JAVA] 제네릭(Generic), 제네릭 클래스, 제네릭 메서드, 와일드카드 (0) | 2024.06.22 |
[JAVA][Exception] Map Duplicate key (0) | 2024.06.15 |
[JAVA] Garbage Collection (0) | 2024.03.26 |
[JAVA] Overriding 과 Overloading 의 차이점 (0) | 2024.02.19 |