Menu
CoddyTech

Comparable 接口

本课属于 Coddy Dart 学习旅程的“面向对象编程”单元。第 72 课,共 110 课。

虽然 == 可以告诉你两个对象是否相等,但有时你需要知道哪个对象排在前面。Comparable 接口可以通过定义自然顺序对对象进行排序。

要让一个类可以进行比较,需要实现 Comparable<T> 并重写 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);
  }
}

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);  // 降序
}
challenge icon

挑战

简单

我们来构建一个任务管理系统,让任务可以按优先级排序!你将创建一个实现 Comparable 接口的 Task 类,这样任务列表就能按优先级从高到低自动排序。

你将把代码整理到两个文件中:

  • task.dart:创建一个 Task 类,用来表示待办事项,它包含 name(String)和 priority(int,数字越大表示优先级越高)。你的任务类应实现 Comparable<Task>,这样排序后,任务就会按优先级降序排列(优先级最高的任务排在最前面)。还要重写 toString(),使其返回以下格式:[name] (Priority: [priority])
  • main.dart:导入任务文件,并演示 Comparable 接口如何实现自动排序。创建一个包含以下四个任务的列表:
    • 优先级为 2 的 'Write report'
    • 优先级为 5 的 'Fix critical bug'
    • 优先级为 1 的 'Update documentation'
    • 优先级为 3 的 'Review code'
    打印 Before sorting:,然后打印每个任务。使用 sort() 对列表排序,打印一个空行,然后打印 After sorting:,再依次打印每个任务。

由于你的 Task 类实现了 Comparable,你可以直接对列表调用 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)

亲手试试

import 'task.dart';

void main() {
  // TODO: 创建一个包含以下 Task 对象的列表:
  // - 'Write report',优先级为 2
  // - 'Fix critical bug',优先级为 5
  // - 'Update documentation',优先级为 1
  // - 'Review code',优先级为 3
  
  List<Task> tasks = [
    // TODO: 在这里添加这四个任务
  ];
  
  // TODO: 打印 "Before sorting:"
  // TODO: 打印列表中的每个任务
  
  // TODO: 使用 sort() 对列表排序
  
  // TODO: 打印一个空行
  
  // TODO: 打印 "After sorting:"
  // TODO: 打印排序后列表中的每个任务
}
quiz icon自我测试

这节课包含一个小测验。开始学习即可作答,并记录你的进度。

面向对象编程中的所有课

自己练习: Dart 在线编译器