Comparable インターフェース
CoddyのDartジャーニー「オブジェクト指向プログラミング」セクションの一部 — レッスン 72/110。
== は2つのオブジェクトが等しいかどうかを教えてくれますが、時にはどちらが先に来るかを知る必要がある場合があります。Comparable インターフェースを使用すると、自然な順序を定義することでオブジェクトをソートできるようになります。
クラスを比較可能にするには、Comparable<T>を実装し、compareToメソッドをオーバーライドします。このメソッドは、thisがotherより前に来る場合は負の数を、等しい場合はゼロを、thisが後に来る場合は正の数を返します:
class Student implements Comparable<Student> {
String name;
int grade;
Student(this.name, this.grade);
@override
int compareTo(Student other) {
return grade.compareTo(other.grade);
}
}
void main() {
var students = [
Student('Alice', 85),
Student('Bob', 92),
Student('Carol', 78),
];
students.sort();
for (var s in students) {
print('${s.name}: ${s.grade}');
}
// Carol: 78, Alice: 85, Bob: 92
}クラスが Comparable を実装すると、カスタムのコンパレータを指定せずに sort() を使用できるようになります。組み込みの数値型や文字列型はすでに Comparable を実装しているため、grade.compareTo(other.grade) が直接動作します。
降順にするには、オブジェクトを入れ替えるか、結果を反転させて比較を逆にするだけです。
@override
int compareTo(Student other) {
return other.grade.compareTo(grade); // 降順
}チャレンジ
簡単タスクを優先度順にソートできるタスク管理システムを構築しましょう!Comparableインターフェースを実装したTaskクラスを作成し、タスクのリストを優先度の高い順から低い順に自動的にソートできるようにします。
コードを2つのファイルに整理します:
task.dart:name(String) とpriority(int、数値が高いほど優先度が高い) を持つToDoアイテムを表すTaskクラスを作成します。ソートした際にタスクが優先度の降順(優先度が高い順)で表示されるように、Comparable<Task>を実装してください。また、toString()をオーバーライドして、[name] (Priority: [priority])という形式を返すようにします。main.dart: タスクファイルをインポートし、Comparableインターフェースによって自動ソートがどのように可能になるかを実演します。以下の4つのタスクを含むリストを作成してください:'Write report'優先度2'Fix critical bug'優先度5'Update documentation'優先度1'Review code'優先度3
Before sorting:と出力し、次に各タスクを出力します。sort()を使用してリストをソートし、空行を出力した後、After sorting:と出力し、続いて各タスクを再度出力します。
Task クラスが Comparable を実装しているため、カスタムの比較関数(comparator)を指定することなく、リストに対して直接 sort() を呼び出すことができます。タスクは compareTo の実装に基づいて自動的に整列されます!
期待される出力:
Before sorting:
Write report (Priority: 2)
Fix critical bug (Priority: 5)
Update documentation (Priority: 1)
Review code (Priority: 3)
After sorting:
Fix critical bug (Priority: 5)
Review code (Priority: 3)
Write report (Priority: 2)
Update documentation (Priority: 1)チートシート
Comparable インターフェースを使用すると、オブジェクトはソートのための自然な順序を定義できます。Comparable<T> を実装し、compareTo メソッドをオーバーライドします。
compareTo メソッドは以下を返します:
thisがotherより前にある場合は負の数- 両者が等しい場合は 0
thisがotherより後にある場合は正の数
基本的な実装(昇順):
class Student implements Comparable<Student> {
String name;
int grade;
Student(this.name, this.grade);
@override
int compareTo(Student other) {
return grade.compareTo(other.grade);
}
}クラスが Comparable を実装すると、カスタム比較関数を指定せずに sort() を使用できます:
var students = [
Student('Alice', 85),
Student('Bob', 92),
Student('Carol', 78),
];
students.sort(); // 自動的に compareTo を使用します降順にするには、比較を逆にします:
@override
int compareTo(Student other) {
return other.grade.compareTo(grade); // 降順
}自分で試してみよう
import 'task.dart';
void main() {
// TODO: 次の内容で Task オブジェクトのリストを作成してください:
// - 優先度 2 の 'Write report'
// - 優先度 5 の 'Fix critical bug'
// - 優先度 1 の 'Update documentation'
// - 優先度 3 の 'Review code'
List<Task> tasks = [
// TODO: ここに 4 つのタスクを追加してください
];
// TODO: "Before sorting:" と出力してください
// TODO: リスト内の各タスクを出力してください
// TODO: sort() を使用してリストをソートしてください
// TODO: 空行を出力してください
// TODO: "After sorting:" と出力してください
// TODO: ソートされたリスト内の各タスクを出力してください
}
このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。
オブジェクト指向プログラミングのすべてのレッスン
4Null Safety
Null Safety 入門Nullable と Non-Nullable? 演算子と ! 演算子late キーワードと Null SafetyNull-Aware 演算子クラスにおける Null Safetyまとめ:ユーザープロフィールシステム10コレクションとジェネリクス
List, Set, Map の概要型安全なコレクションジェネリッククラスジェネリックメソッドジェネリクスの制約Iterable と Iteratorまとめ:ジェネリックなストレージ11特殊メソッド
toString() のオーバーライドhashCode と == のオーバーライドComparable インターフェースcall() メソッドnoSuchMethod のオーバーライドまとめ:カスタムコレクション