Comparable과 Comparator
자바에 익숙해지기 위해 프로그래머스를 풀던중 정렬 관련에 대해 코딩할 때, Comparator와 Comparable에 대해 알게 되었고 이해와 정리가 필요하다는 생각을 하게 되어 정리하려고 합니다.
Arrays.sort()을 호출하여 정렬하는데 사실 이 정렬기능은 Comparable의 구현에 의해 정렬된 것입니다. 정렬을 하려면 '기준'이 필요한데, Comparator와 Comparable은 모두 인터페이스로 객체를 비교할 수 있도록 만들게 하고, 이것을 사용하려고 하면 인터페이스니 선언된 메소드를 반드시 구현을 해야 합니다.
public interface Comparator<T> {
int compare(T o1, T o2);
}
public interface Comparable<T> {
public int compareTo(T o);
}
위 코드를 보면 매개변수의 개수부터 다른데, Comparator는 두 매개변수 객체를 비교하는 것이고, Comparable은 자기 자신과 매개변수 객체를 비교합니다.
compareTo()의 반환 값은 Int이지만 두 객체가 같으면 0, 비교하는 값보다 크면 양수 작으면 음수를 반환하도록 구현을 해야 하고, compare()도 객체를 비교해서 음수, 0, 양수 중 하나를 반환하도록 구현해야 합니다.
❗오른쪽이 크면 음수, 작으면 양수를 반환합니다.
▪️Comparable:
기본 정렬 기준을 구현하는 데 사용
▪️Comparator
기본 정렬 기준 외에 다른 기준으로 정렬하고자 할 때 사용
🏷️ Comparable
Comparable은 자기 자신과 매개변수 객체를 비교합니다.
import java.util.ArrayList;
import java.util.Collections;
class User implements Comparable<User>{
private String name;
private int age;
// 생성자, getter 생략
@Override
public int compareTo(User o) {
// if (this.age > o.age) {
// return 1;
// } else if (this.age == o.age) {
// return 0;
// } else{
// return -1;
// }
return this.age - o.age;
}
}
public class Example {
public static void main(String[] args) {
ArrayList<User> userList = new ArrayList<>();
userList.add(new User("Kim", 31));
userList.add(new User("Kang", 29));
userList.add(new User("Park", 32));
Collections.sort(userList);
for (User user : userList) {
System.out.println(user.getName());
}
}
// 출력 : ["Kang", "Kim", "Park"]
}
주석과 같이 자신과 상대방과의 차이를 비교하여 크면 1, 같으면 0, 작으면 -1를 반환하도록 구현을 하면, 나이가 많을수록 뒤에 위치하는 오름차순으로 구현할 수 있습니다.
return (this.age - o.age) * -1;
내림 차순으로 정렬을 하고 싶은 경우 위와 같이 코드를 작성하면 됩니다.
🏷️ Comparator
두 매개변수 객체를 비교하여 정렬합니다.
import java.util.ArrayList;
import java.util.Collections;
class User implements Comparable<User>{
private String name;
private int age;
// 생성자, getter 생략
}
class AgeSort implements Comparator<User> {
@Override
public int compare(User o1, User o2) {
return o1.getAge() - o2.getAge();
}
}
public class Example {
public static void main(String[] args) {
ArrayList<User> userList = new ArrayList<>();
AgeSort ageSort = new AgeSort();
userList.add(new User("Kim", 40));
userList.add(new User("Kang", 30));
userList.add(new User("Park", 28));
Collections.sort(userList, ageSort);
for (User user : userList) {
System.out.println(user.getName());
}
}
// 출력 : ["Park", "Kang", "Kim"]
}
userList를 나이 기준으로 오름차순 정렬을 했습니다. 그러나 정렬 알고리즘을 여러 번 사용할 것이 아니라 한 번만 사용할 거면 아래와 같이 익명 클래를 사용해도 됩니다.
public class Example {
public static void main(String[] args) {
ArrayList<User> userList = new ArrayList<>();
userList.add(new User("Kim", 40));
userList.add(new User("Kang", 30));
userList.add(new User("Park", 28));
Collections.sort(
userList,
new Comparator<User>() {
@Override
public int compare(User o1, User o2) {
return o1.getAge() - o2.getAge();
}
}
);
for (User user : userList) {
System.out.println(user.getName());
}
}
// 출력 : ["Park", "Kang", "Kim"]
}
🏷️ 결론
Comparable은 자기 자신과 파라미터로 들어오는 객체를 비교하는 것이고 Comparator는 자기 자신의 상태가 어떻던 상관없이 파라미터로 들어오는 두 객체를 비교하는 것입니다. 즉, 비교한다는 것은 같지만 비교 대상이 다르다고 볼 수 있습니다.
📖 Reference
'코딩 공부 > web & Java' 카테고리의 다른 글
[Spring] BCryptPasswordEncoder (0) | 2025.04.04 |
---|---|
[Java] Stream (0) | 2025.04.02 |
[JPA] CRUDRepository와 JPARepository (0) | 2025.04.01 |
[Mockito] ArgumentMatchers 및 any,eq (1) | 2024.10.21 |
[JPA] @PrePersist와 @PreUpdate (0) | 2024.10.18 |