compareTo() と Comparable
CoddyのJavaジャーニー「オブジェクト指向プログラミング」セクションの一部。レッスン 44/87。
Comparableインターフェースを使用すると、オブジェクトに自然順序を定義できます。このインターフェースを実装することで、クラスをCollections.sort()などのメソッドを使って自動的に並べ替えたり、TreeSetのようなソート済みコレクションに格納したりできます。
このインターフェースでは、単一のメソッドを実装する必要があります:compareTo()。このメソッドは現在のオブジェクトと別のオブジェクトを比較し、それらの相対的な順序を示す整数を返します。
- 負の値: このオブジェクトはもう一方のオブジェクトより前に来ます
- ゼロ: 両方のオブジェクトは等しいです
- 正の値: このオブジェクトはもう一方のオブジェクトより後に来ます
public class Person implements Comparable<Person> {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public int compareTo(Person other) {
return Integer.compare(this.age, other.age); // 年齢の昇順でソート
}
}実装すると、並べ替えは簡単になります。
List<Person> people = new ArrayList<>();
people.add(new Person("Alice", 30));
people.add(new Person("Bob", 25));
Collections.sort(people); // 年齢でソート済み: Bob, Alice文字列やその他の Comparable フィールドを比較する場合は、減算を使う代わりに、それらの compareTo() メソッドに委譲できます:return this.name.compareTo(other.name);。この方法はより安全で、エッジケースも適切に処理します。int フィールドでは、a - b よりも Integer.compare(a, b) を優先してください。極端な値では減算によってオーバーフローが発生する可能性があるためです。
チャレンジ
簡単映画を評価順に並べ替えるためにComparableインターフェースを使用する、映画ランキングシステムを作成しましょう。ほかの映画との比較方法を把握しているMovieクラスを作成し、評価の高い順から低い順への自動並べ替えを可能にします。
コードを2つのファイルに分けて整理します。
Movie.java: ほかの映画と比較できる映画を表すクラスをCreateします。Movieには3つのprivateフィールドがあります。title(String)、director(String)、rating(double、0.0から10.0まで)です。すべてのフィールドを初期化するconstructorと、それぞれのgetterメソッドを含めてください。Movieクラスに
Comparable<Movie>をimplementし、compareTo()メソッドをオーバーライドしてください。映画は評価のdescending order(評価の高いものを先頭)で並べ替える必要があります。doubleを比較するときは、安全な比較のためにDouble.compare()を使用してください。descending sortでは順序を逆にすることを忘れないでください。toString()をオーバーライドし、次を返すようにしてください。[title] by [director] - Rating: [rating]Main.java: 映画のlistを作成して並べ替えることで、Movieクラスを実際に動作させます。3つの映画の入力を受け取ります。各映画は別々のlineに、次のformatで記述されます。title,director,rating各lineを解析してMovieオブジェクトを作成し、それらを
ArrayListにaddした後、Collections.sort()を使用してlistを並べ替えます。Comparableの実装のおかげで、映画は自動的にrating順に並びます。並べ替えた後、
toString()のformatを使用して、各映画をそれぞれ別のlineに出力します。評価が最も高い映画が先頭に表示されます。
3つのlineの入力を受け取ります。各lineには、次のformatの映画データが含まれます。title,director,rating
たとえば、入力lineは次のようになります。Inception,Christopher Nolan,8.8
Mainファイルでは、java.util.ArrayList、java.util.Collections、java.util.Scannerを忘れずにimportしてください。Comparableをimplementすると、1回のメソッド呼び出しだけで独自のオブジェクトを並べ替えられることに注目してください。追加のcomparatorは必要ありません。
自分で試してみよう
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行を読み取る
String line1 = scanner.nextLine();
String line2 = scanner.nextLine();
String line3 = scanner.nextLine();
// TODO: Movieオブジェクトを格納するArrayListを作成する
// TODO: 各行を解析する(形式: title,director,rating)
// Hint: 各部分を分けるにはsplit(",")を使う
// Hint: 評価にはDouble.parseDouble()を使う
// TODO: Movieオブジェクトを作成してリストに追加する
// TODO: Collections.sort()を使ってリストをソートする
// TODO: 各映画を出力する(1行に1つ)
}
}
このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。
オブジェクト指向プログラミングのすべてのレッスン
4継承
継承の基本 (extends)super キーワードメソッドのオーバーライド (@Override)コンストラクタチェーンObject クラス単一継承と多段階継承なぜ多重継承ができないのかまとめ:従業員の階層構造7特殊メソッドとObjectクラス
toString() メソッドequals() と hashCode()clone() メソッドcompareTo() と ComparableComparator インターフェースまとめ - カスタムソート自分で練習してみよう: Javaオンラインコンパイラ