Comparable이란?
자바의 Comparable 인터페이스는 객체를 정렬 가능한 객체로 만들어주는 인터페이스입니다.
이를 통해 특정 객체들이 자연 순서를 정의하고 이를 기반으로 정렬될 수 있게 합니다.
Comparable 인터페이스를 구현하는 클래스는 compareTo 메소드를 오버라이드하여 그 객체의 순서를 지정합니다.
Comparable<T> 인터페이스 사용법
정렬하고자 하는 객체에 Comparable 인터페이스를 구현하면 됩니다.
public class Person implements Comparable<Person> {
private String name;
private Integer birthYear;
public Person(String name, Integer birthYear) {
this.name = name;
this.birthYear = birthYear;
}
@Override
public int compareTo(Person o) {
// 태어난 년도 기준 정렬
return birthYear.compareTo(o.birthYear);
}
@Override
public String toString() {
return "Person{name='" + name + "', birthYear=" + birthYear + "}";
}
}
Comparable 인터페이스의 compareTo 메소드를 오버라이딩하여 객체의 정렬 기준을 지정하였습니다.
Comparable 인터페이스 적용 예제
위의 Person 클래스는 birthYear를 기준으로 정렬됩니다. 다음은 Person 객체를 생성하고 정렬하는 예제입니다.
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class Main {
public static void main(String[] args) {
// 객체 생성
Person person1 = new Person("Kim", 1990);
Person person2 = new Person("Lee", 1980);
Person person3 = new Person("Choi", 2000);
List<Person> people = new ArrayList<>();
people.add(person1);
people.add(person2);
people.add(person3);
// Comparable의 compareTo 메소드를 사용
Collections.sort(people);
System.out.println(people);
}
}
출력 결과입니다.
[Person{name='Lee', birthYear=1980}, Person{name='Kim', birthYear=1990}, Person{name='Choi', birthYear=2000}]
정렬 기준 변경
compareTo 메소드를 수정하여 정렬 기준을 변경할 수 있습니다.
예를 들어, 이름을 기준으로 정렬하려면 다음과 같이 변경할 수 있습니다.
// Person 객체의 compareTo 메소드 수정
@Override
public int compareTo(Person o) {
// 이름 사전순 정렬
return name.compareTo(o.name);
}
변경된 정렬 기준이 적용되었습니다.
Comparable이 적용되는 곳
Comparable 인터페이스는 주로 정렬하는 메소드에서 사용됩니다.
- Collections.sort: 리스트를 정렬합니다.
- Arrays.sort: 배열을 정렬합니다.
// 정렬
Collections.sort(list);
Arrays.sort(array);
또한, TreeSet이나 TreeMap과 같은 자료구조에서도 Comparable 인터페이스를 사용하여 내부적으로 정렬합니다.
// TreeSet
Set<Person> personSet = new TreeSet<>();
personSet.add(person1);
personSet.add(person2);
personSet.add(person3);
System.out.println("personSet = " + personSet);
// TreeMap
Map<Person, Integer> personMap = new TreeMap<>();
personMap.put(person1, 0);
personMap.put(person2, 0);
personMap.put(person3, 0);
System.out.println("personMap = " + personMap);
TreeSet이나 TreeMap은 값을 정렬한 채로 저장이 되는데, 정렬할 때 Comparable을 사용합니다.
만약에 객체에 Comparable이 없다면 Set이나 Map 생성 시 Comparator 객체를 통해 정렬 기준을 설정할 수 있습니다.
Comparator를 통한 정렬
만약 Comparable 인터페이스를 구현하지 않은 클래스의 객체를 정렬하거나 다른 정렬 기준을 적용하고 싶다면, Comparator 인터페이스를 사용할 수 있습니다.
import java.util.Comparator;
import java.util.List;
public class PersonComparatorByName implements Comparator<Person> {
@Override
public int compare(Person p1, Person p2) {
return p1.getName().compareTo(p2.getName());
}
public static void main(String[] args) {
List<Person> people = List.of(
new Person("Kim", 1990),
new Person("Lee", 1980),
new Person("Choi", 2000)
);
// Comparator를 사용하여 정렬
people.sort(new PersonComparatorByName());
System.out.println(people);
}
}
위 예제의 출력 결과입니다.
[Person{name='Choi', birthYear=2000}, Person{name='Kim', birthYear=1990}, Person{name='Lee', birthYear=1980}]
읽으면 좋은 글
[Java] String - compareTo : 문자열 사전순 비교