Menu
Coddy logo textTech

Comparator インターフェース

CoddyのJavaジャーニー「オブジェクト指向プログラミング」セクションの一部。レッスン 45/87。

Comparableはクラスの自然順序を定義しますが、オブジェクトを異なる方法で並べ替える必要がある場合もあります。Comparatorインターフェースを使うと、元のクラスを変更せずに、個別の比較ロジックを作成できます。

Comparatorは、同じ型の2つのオブジェクトを比較する外部オブジェクトです。複数の並べ替えオプションが必要な場合や、クラス自体を変更できない場合に便利です。

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 は関数型インターフェースなので、ラムダ式を使用できます。

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

主な違いは次のとおりです。Comparableは比較されるクラスによって実装され、1つの自然順序を定義します。一方、Comparatorは別個のクラスであり、無制限のカスタム順序を定義できます。

challenge icon

チャレンジ

簡単

Comparator interface の力を示す、Employee の並べ替えシステムを構築しましょう。Employee クラス自体を変更せずに、salary と name によって Employee を異なる方法で並べ替える複数の comparator を作成します。

コードを4つのファイルに整理します。

  • Employee.java: Employee を表すクラスを作成し、3つの private な fields、name(String)、department(String)、salary(double)を定義します。すべての fields を初期化する constructor と、それぞれの getter メソッドを含めます。toString() をオーバーライドし、次を返すようにします: [name] ([department]) - $[salary]
  • SalaryComparator.java: salary の descending order(給与が highest の Employee が先)で Employee を並べ替える comparator を作成します。Comparator<Employee> interface とその compare() メソッドを Implement します。salary の値を安全に比較するために Double.compare() を使用します。
  • NameComparator.java: name のアルファベット順に ASCENDING(A から Z)で Employee を並べ替える別の comparator を作成します。Comparator<Employee> を Implement し、比較には String の compareTo() メソッドを使用します。
  • Main.java: Employee の list を作成し、comparator を使用して並べ替えることで、すべてをまとめます。3人の Employee の input を受け取ります。それぞれ別の line に、次の format で入力されます: name,department,salary

    Employee の ArrayList を作成し、次の2つの並べ替え方法を示します。

    1. まず、SalaryComparator を使用して salary で並べ替え、それぞれの Employee を出力します
    2. empty line を出力します
    3. 次に、NameComparator を使用して name で並べ替え、それぞれの Employee を出力します

Employee のデータを含む3本の input line を受け取ります。それぞれ次の format です: name,department,salary

たとえば、input line は次のようになります: Alice,Engineering,75000.0

comparator ファイルでは java.util.Comparator を、Main ファイルでは java.util.ArrayListjava.util.Collectionsjava.util.Scanner を import することを忘れないでください。comparator によって、外部で複数の並べ替え戦略を定義できることに注目してください。Employee クラスは、自分がどのように並べ替えられるかについて何も知る必要がありません。

自分で試してみよう

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);
        
        // 入力から3人の従業員を読み取る
        // 各行の形式: name,department,salary
        String line1 = scanner.nextLine();
        String line2 = scanner.nextLine();
        String line3 = scanner.nextLine();
        
        // TODO: 各行を解析してEmployeeオブジェクトを作成する
        // ヒント: 値を区切るにはsplit(",")を使用する
        
        // TODO: 従業員のArrayListを作成し、3つすべてを追加する
        
        // TODO: SalaryComparatorを使用して給与でソートし、各従業員を出力する
        // ヒント: Collections.sort(list, comparator)を使用する
        
        // TODO: 空行を出力する
        
        // TODO: NameComparatorを使用して名前でソートし、各従業員を出力する
    }
}
quiz icon腕試し

このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。

オブジェクト指向プログラミングのすべてのレッスン

自分で練習してみよう: Javaオンラインコンパイラ