Java
 Computer >> コンピューター >  >> プログラミング >> Java

JavaのcompareTo()メソッドとcompare()メソッドの違いを徹底解説

Javaでオブジェクトを並べ替える際に登場するのが、ComparableインターフェースのcompareTo()メソッドと、Comparatorインターフェースのcompare()メソッドです。名前はよく似ていますが、役割や使い方には明確な違いがあります。

Comparableインターフェースが提供するcompareTo()メソッドは、オブジェクトの順序付けを決めるためのもので、この順序は自然順序付け(natural ordering)、このメソッドは自然比較メソッドと呼ばれます。一方、Comparatorインターフェースが提供するcompare()メソッドはソート処理を実行するためのもので、これを使えば複数の並べ替え条件を自由に定義できます。つまり、年齢や名前など、複数のデータメンバーを基準にオブジェクトをソートできるのです。

compareTo()メソッドとは

compareTo()メソッドは、自分自身(this)のオブジェクトと引数で渡されたオブジェクトo1を比較し、その結果を整数値として返します。

構文

public int compareTo(Object o1)
  • このオブジェクトがo1より小さい場合に限り、負の数を返します。
  • このオブジェクトがo1より大きい場合に限り、正の数を返します。
  • このオブジェクトがo1と等しい場合に限り、0を返します。

コード例

import java.util.*;

class Employee implements Comparable {
    String name;
    int age;

    Employee(String name, int age) {
        this.name = name;
        this.age = age;
    }

    // compareToメソッドをオーバーライド
    @Override
    public int compareTo(Object o) {
        return this.age - ((Employee) o).age;
    }
}

public class ComparableDemo {
    public static void main(String[] args) {
        // オブジェクトの生成
        List list = new ArrayList<>();
        // データの追加
        list.add(new Employee("Krishna", 30));
        list.add(new Employee("Archana", 28));
        list.add(new Employee("Vineet", 25));
        list.add(new Employee("Ramesh", 38));
        list.add(new Employee("Alok", 28));

        System.out.println("Before sorting:");
        for (Employee e : list) {
            System.out.print("[ EMP : age = " + e.age + " ] ");
        }

        // ソート処理
        Collections.sort(list);

        System.out.println("After sorting:");
        for (Employee e : list) {
            System.out.print("[ EMP : age = " + e.age + " ] ");
        }
    }
}

実行結果

Before sorting:
[ EMP : age = 30 ] [ EMP : age = 28 ] [ EMP : age = 25 ] [ EMP : age = 38 ] [ EMP : age = 28 ]
After sorting:
[ EMP : age = 25 ] [ EMP : age = 28 ] [ EMP : age = 28 ] [ EMP : age = 30 ] [ EMP : age = 38 ]

このように、Comparableを実装したクラスでは、Collections.sort()を呼び出すだけで、クラス内に定義された自然順序(ここでは年齢の昇順)に従って自動的に並べ替えられます。

compare()メソッドとは

compare()メソッドは、第1引数のオブジェクトo1と第2引数のオブジェクトo2を比較し、その結果を整数値として返します。

構文

public int compare(Object o1, Object o2)
  • o1がo2より小さい場合に限り、負の数を返します。
  • o1がo2より大きい場合に限り、正の数を返します。
  • o1がo2と等しい場合に限り、0を返します。

コード例

import java.util.*;

class Student {
    String name;
    int age, roll;

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

// 年齢で比較するComparator
class AgeComparator implements Comparator {
    @Override
    public int compare(Object o1, Object o2) {
        return ((Student) o1).age - ((Student) o2).age;
    }
}

// 出席番号で比較するComparator
class RollComparator implements Comparator {
    @Override
    public int compare(Object o1, Object o2) {
        return ((Student) o1).roll - ((Student) o2).roll;
    }
}

public class ComparatorDemo {
    public static void main(String[] args) {
        List list = new ArrayList<>();
        list.add(new Student("Ramesh", 30, 20));
        list.add(new Student("Adithya", 7, 10));
        list.add(new Student("Krishna", 25, 5));
        list.add(new Student("Vineet", 24, 15));

        System.out.println("BEFORE SORTING");
        for (Student e : list) {
            System.out.println("[ STU : name = " + e.name + " age = " + e.age + " roll = " + e.roll + "]");
        }

        // 年齢を基準にソート
        Collections.sort(list, new AgeComparator());
        System.out.println("AFTER SORTING WITH AGE");
        for (Student e : list) {
            System.out.println("[ STU : name = " + e.name + " age = " + e.age + " ]");
        }

        // 出席番号を基準にソート
        Collections.sort(list, new RollComparator());
        System.out.println("AFTER SORTING WITH ROLL");
        for (Student e : list) {
            System.out.println("[ STU : name = " + e.name + " roll = " + e.roll + " ]");
        }
    }
}

実行結果

BEFORE SORTING
[ STU : name = Ramesh age = 30 roll = 20 ]
[ STU : name = Adithya age = 7 roll = 10 ]
[ STU : name = Krishna age = 25 roll = 5 ]
[ STU : name = Vineet age = 24 roll = 15 ]
AFTER SORTING WITH AGE
[ STU : name = Adithya age = 7 ]
[ STU : name = Vineet age = 24 ]
[ STU : name = Krishna age = 25 ]
[ STU : name = Ramesh age = 30 ]
AFTER SORTING WITH ROLL
[ STU : name = Krishna roll = 5 ]
[ STU : name = Adithya roll = 10 ]
[ STU : name = Vineet roll = 15 ]
[ STU : name = Ramesh roll = 20 ]

Comparatorを使うと、同じStudentクラスに対して「年齢順」「出席番号順」といった異なる並べ替え基準を、ソート時に切り替えて適用できる点が大きな特徴です。

compareTo()とcompare()の違いまとめ

比較ポイントcompareTo()compare()
所属するインターフェースjava.lang.Comparablejava.util.Comparator
実装方法比較対象のクラス自身が実装する独立したComparatorクラスとして実装する
引数の数1個(自分との比較相手)2個(比較対象が2つ)
並べ替えの基準クラスごとに1つの自然順序のみ年齢・出席番号など複数の基準を切り替え可能
呼び出し例Collections.sort(list)Collections.sort(list, comparator)

まとめると、クラス本来の標準的な並び順を定義したい場合はcompareTo()(Comparable)、状況に応じて複数の並べ替え基準を使い分けたい場合はcompare()(Comparator)を選ぶのが基本です。用途に応じて適切に使い分けることで、柔軟で保守性の高いソート処理を実現できます。

  1. JavaのJFrameとJDialogの違いとは?特徴と使い分けを解説

    JavaのSwingには、ウィンドウを表示するためのトップレベルコンテナとしてJFrameとJDialogが用意されています。どちらもよく似た役割を持ちますが、動作や用途には重要な違いがあります。この記事では、それぞれの特徴をサンプルコードとともに解説し、最後に使い分けのポイントをまとめます。 JFrameとは フレームに追加されたコンポーネントは「コンテンツ」として扱われ、contentPaneによって管理されます。JFrameにコンポーネントを追加する際は、フレーム本体ではなくcontentPaneに対して追加する必要があります。 JFrameは、タイトル、境界線、(オプションで)メニュ

  2. JavaのGridLayoutとGridBagLayoutの違いを徹底解説!特徴と使い分けのポイント

    JavaのAWT/Swingには複数のレイアウトマネージャーが用意されていますが、その中でもGridLayoutとGridBagLayoutは、コンポーネントを格子状(グリッド)に配置するという点でよく似ています。しかし、両者には重要な違いがあります。 GridLayoutは、すべてのコンポーネントを矩形のグリッド内に配置し、領域を同じサイズの長方形に分割して、各コンポーネントをそれぞれのセルの中に収めます。一方、GridBagLayoutは柔軟性の高いレイアウトマネージャーであり、コンポーネントのサイズを揃えることなく、縦方向・横方向に整列させて配置できます。各GridBagLayoutオブ