Menu
Coddy logo textTech

Comparator 인터페이스

Coddy Java 여정의 객체 지향 프로그래밍 섹션에 포함된 레슨. 87개 중 45번째.

Comparable은 클래스의 자연 순서를 정의하지만, 때로는 객체를 다양한 방식으로 정렬해야 합니다. Comparator 인터페이스를 사용하면 원래 클래스를 수정하지 않고 별도의 비교 로직을 만들 수 있습니다.

Comparator는 동일한 유형의 두 객체를 비교하는 외부 객체입니다. 여러 정렬 옵션을 원하거나 class 자체를 수정할 수 없을 때 유용합니다:

import java.util.Comparator;

class NameComparator implements Comparator<Person> {
    @Override
    public int compare(Person p1, Person p2) {
        return p1.getName().compareTo(p2.getName());
    }
}

class AgeComparator implements Comparator<Person> {
    @Override
    public int compare(Person p1, Person p2) {
        return p1.getAge() - p2.getAge();
    }
}

그런 다음 comparator를 정렬 메서드에 전달할 수 있습니다:

List<Person> people = new ArrayList<>();
people.add(new Person("Charlie", 30));
people.add(new Person("Alice", 25));

Collections.sort(people, new NameComparator());  // 이름으로 정렬됨
Collections.sort(people, new AgeComparator());   // 나이로 정렬됨

간결한 코드를 위해 Comparator가 함수형 interface이므로 람다 표현식을 사용할 수 있습니다:

Collections.sort(people, (p1, p2) -> p1.getName().compareTo(p2.getName()));

핵심적인 차이점: Comparable은 비교되는 클래스에 의해 구현되어 하나의 자연 순서를 정의하는 반면, Comparator는 무제한으로 사용자 지정 순서를 정의할 수 있는 별도의 클래스입니다.

challenge icon

챌린지

쉬움

Comparator 인터페이스의 강력한 기능을 보여 주는 직원 정렬 시스템을 만들어 봅시다. Employee 클래스 자체를 수정하지 않고 급여와 이름을 기준으로 직원을 여러 방식으로 정렬할 수 있도록 여러 comparator를 만들게 됩니다.

코드를 네 개의 파일로 구성합니다:

  • Employee.java: 직원을 나타내는 class를 만듭니다. name (String), department (String), salary (double)의 세 private fields를 포함합니다. 모든 fields를 초기화하는 constructor와 각 field에 대한 getter 메서드를 포함하세요. toString()을 재정의하여 다음을 반환하도록 합니다: [name] ([department]) - $[salary]
  • SalaryComparator.java: 직원들을 salary 기준으로 내림차순 (가장 높은 급여부터) 정렬하는 comparator를 만듭니다. Comparator<Employee> interface와 해당 compare() 메서드를 Implement하세요. salary 값을 안전하게 비교하려면 Double.compare()를 사용합니다.
  • NameComparator.java: 직원들을 이름의 알파벳순으로 오름차순 (A부터 Z까지) 정렬하는 또 다른 comparator를 만듭니다. Comparator<Employee>를 Implement하고 String의 compareTo() 메서드를 사용하여 비교합니다.
  • Main.java: 직원 list를 만들고 comparator를 사용하여 정렬함으로써 모든 내용을 하나로 연결합니다. 세 직원의 input을 받으며, 각 직원은 다음 format의 별도 line에 입력됩니다: name,department,salary

    직원들의 ArrayList를 create한 다음 두 가지 정렬 방식을 보여 줍니다:

    1. 먼저 SalaryComparator를 사용하여 salary 기준으로 정렬하고 각 직원을 출력합니다
    2. empty line을 출력합니다
    3. 그런 다음 NameComparator를 사용하여 이름 기준으로 정렬하고 각 직원을 출력합니다

각 line에 직원 data가 name,department,salary format으로 포함된 세 줄의 input을 받습니다.

예를 들어 input line은 다음과 같을 수 있습니다: Alice,Engineering,75000.0

comparator 파일에서는 java.util.Comparator를, Main 파일에서는 java.util.ArrayList, java.util.Collections, java.util.Scanner를 import해야 합니다. comparator를 사용하면 외부에서 여러 정렬 전략을 정의할 수 있다는 점에 주목하세요. Employee class는 자신이 어떤 방식으로 정렬될 수 있는지 전혀 알 필요가 없습니다!

직접 해보기

import java.util.ArrayList;
import java.util.Collections;
import java.util.Scanner;

class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        
        // 입력에서 세 명의 직원을 읽습니다
        // 각 줄 형식: name,department,salary
        String line1 = scanner.nextLine();
        String line2 = scanner.nextLine();
        String line3 = scanner.nextLine();
        
        // TODO: 각 줄을 파싱하고 Employee 객체를 생성하세요
        // 힌트: 값을 분리하려면 split(",")를 사용하세요
        
        // TODO: 직원들의 ArrayList를 생성하고 세 명을 모두 추가하세요
        
        // TODO: SalaryComparator를 사용하여 급여별로 정렬하고 각 직원을 출력하세요
        // 힌트: Collections.sort(list, comparator)를 사용하세요
        
        // TODO: 빈 줄을 출력하세요
        
        // TODO: NameComparator를 사용하여 이름별로 정렬하고 각 직원을 출력하세요
    }
}
quiz icon실력 점검

이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.

객체 지향 프로그래밍의 모든 레슨

직접 연습해 보세요: 온라인 Java 컴파일러