Programming/Java

[Java] Comparator, Comparable 인터페이스

kmindev 2023. 11. 3. 15:45

 

남궁성님의 Java의 정석(3rd Edition)을 보고 정리한 글입니다.

 

1. Comparator, Comparable

  • 객체를 정렬하는데 필요한 메서드를 정의한 인터페이스(정렬기준을 제공)
  • Comparator는 compare(Object o1, Object o2) 메서드를 통해 객체를 비교한다.
    • 두 객체(매개변수)로 비교한다.
  • Comparable는 compareTo(Object o1) 메서드를 통해 객체를 비교한다.
    • 자기자신과 매개변수 객체를 비교한다.
  • compare(), compareTo() 모두 두 객체가 같으면 0, 비교하는 값보다 작으면 음수, 크면 양수를 리턴하도록 구현해야 한다. 

 

a. Comparator 예제

  • age(나이)를 기준으로 오름차순 정렬
class Student implements Comparator<Student> {
    String name;
    int age;
    int num;

		 public Student() {}

    public Student(String name, int age, int num) {
        this.name = name;
        this.age = age;
        this.num = num;
    }

    @Override
    public int compare(Student o1, Student o2) {
        return o1.age - o2.age; // age를 기준으로 오름차순 정렬
    }

    @Override
    public String toString() {
        return name;
    }
}

public class Main {
    public static void main(String[] args) {
        List<Student> students = new ArrayList<Student>();
        students.add(new Student("홍길동", 20, 2));
        students.add(new Student("이순신", 21, 3));
        students.add(new Student("세종대왕", 40, 1));

        Collections.sort(students, new Student()); // Comparator 구현 객체를 넘겨줘야 함.

        System.out.println(students);

    }
}

실행결과
[홍길동, 이순신, 세종대왕]

 

 

b. Comparable 예제

  • num을 기준으로 오름차순 정렬
class Student implements Comparable<Student> {
    String name;
    int age;
    int num;

    public Student() {}

    public Student(String name, int age, int num) {
        this.name = name;
        this.age = age;
        this.num = num;
    }

    @Override
    public int compareTo(Student o) {
        return this.num - o.num; // num을 기준으로 정렬
    }

    @Override
    public String toString() {
        return name;
    }
}

public class Main {
    public static void main(String[] args) {
        List<Student> students = new ArrayList<Student>();
        students.add(new Student("홍길동", 20, 2));
        students.add(new Student("이순신", 21, 3));
        students.add(new Student("세종대왕", 40, 1));

        Collections.sort(students); // Comparable 구현 객체라는 것을 넘겨줄 필요 X 

        System.out.println(students);
    }
}

실행결과
[세종대왕, 홍길동, 이순신]

 

c. 주의 사항

  • compare(), compareTo() 메서드 int 타입을 반환하기 때문에 아래 방식은 int의 범위에 벗어나 오버플로우 발생해서 의도하지 않는 결과가 발생할 수 있다.
@Override
public int compare(Student o1, Student o2) {
		return o1.age - o2.age; // age를 기준으로 오름차순 정렬
}

 

 

  • 코드가 간결하다는 점은 좋지만 상황에 따라 잘 판단해서 if문을 사용해야 한다.
@Override
public int compare(Student o1, Student o2) {
	if(o1.age > o2.age) return 1;
	else if (o1.age == o2.age) return 0;
    	else return -1;
}