본문 바로가기
코딩 공부/web & Java

[Java] Comparable과 Comparator

by 현장 2025. 4. 4.

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