当前位置: 首页 > ops >正文

Comparable和Comparator

文章目录

  • 使用 Comparable
  • 使用 Comparator
    • 传统匿名内部类
    • Lambda 表达式
    • 链式调用
  • 总结

在 Java 中,自定义类的排序规则需要通过实现 Comparable 接口或提供 Comparator 来定义。以下是两种主要方式的详细说明:

使用 Comparable

让类本身实现 Comparable<T> 接口,并覆写 compareTo(T o) 方法,定义默认排序规则。

import java.util.Arrays;class Student implements Comparable<Student> {private String name;private int score;public Student(String name, int score) {this.name = name;this.score = score;}@Overridepublic String toString() {return "[" + this.name + ":" + this.score + "]";}@Overridepublic int compareTo(Student o) {// 按分数降序排序,如果分数相同则按姓名升序int scoreDiff = o.score - this.score;if (scoreDiff != 0) {return scoreDiff;}return this.name.compareTo(o.name);}
}public class Test {public static void main(String[] args) {Student[] students = new Student[] {new Student("张三", 95),new Student("李四", 96),new Student("王五", 97),new Student("赵六", 92),};Arrays.sort(students);System.out.println(Arrays.toString(students));}
}

在这里插入图片描述

为了进一步加深对接口的理解, 我们可以尝试自己实现一个 sort 方法来完成刚才的排序过程(使用冒泡排序)

import java.util.Arrays;class Student implements Comparable<Student> {private String name;private int score;public Student(String name, int score) {this.name = name;this.score = score;}@Overridepublic String toString() {return "[" + this.name + ":" + this.score + "]";}@Overridepublic int compareTo(Student o) {// 按分数降序排序,如果分数相同则按姓名升序int scoreDiff = o.score - this.score;if (scoreDiff != 0) {return scoreDiff;}return this.name.compareTo(o.name);}
}public class Test {public static void sort(Comparable[] array) {for (int i = 0; i < array.length - 1; i++) {for (int j = 0; j < array.length - 1 - i; j++) {if (array[j].compareTo(array[j+1]) > 0) {Comparable tmp = array[j];array[j] = array[j+1];array[j+1] = tmp;}}}}public static void main(String[] args) {Student[] students = new Student[] {new Student("张三", 95),new Student("李四", 96),new Student("王五", 97),new Student("赵六", 92),};sort(students);System.out.println(Arrays.toString(students));}
}

在这里插入图片描述

使用 Comparator

不修改原类,通过创建 Comparator<T> 实现类或使用 Lambda 表达式定义临时排序规则。

传统匿名内部类

import java.util.Arrays;
import java.util.Comparator;class Student {private String name;private int score;public Student(String name, int score) {this.name = name;this.score = score;}@Overridepublic String toString() {return "[" + this.name + ":" + this.score + "]";}// Getter方法用于访问私有字段public String getName() { return name; }public int getScore() { return score; }
}public class Test {public static void main(String[] args) {Student[] students = new Student[] {new Student("张三", 95),new Student("李四", 96),new Student("王五", 97),new Student("赵六", 92),};// 使用Comparator实现降序排序Comparator<Student> comparator = new Comparator<Student>() {@Overridepublic int compare(Student s1, Student s2) {return Integer.compare(s2.getScore(), s1.getScore()); // 手动实现降序}};// 传入Comparator进行排序Arrays.sort(students, comparator);System.out.println(Arrays.toString(students));}
}

Lambda 表达式

import java.util.Arrays;
import java.util.Comparator;class Student {private String name;private int score;public Student(String name, int score) {this.name = name;this.score = score;}@Overridepublic String toString() {return "[" + this.name + ":" + this.score + "]";}// Getter方法用于访问私有字段public String getName() { return name; }public int getScore() { return score; }
}public class Test {public static void main(String[] args) {Student[] students = new Student[] {new Student("张三", 95),new Student("李四", 96),new Student("王五", 97),new Student("赵六", 92),};// 使用Comparator实现降序排序Comparator<Student> comparator = (s1, s2) -> s2.getScore() - s1.getScore();// 传入Comparator进行排序Arrays.sort(students, comparator);System.out.println(Arrays.toString(students));}
}

在这里插入图片描述

链式调用

import java.util.Arrays;
import java.util.Comparator;class Student {private String name;private int score;public Student(String name, int score) {this.name = name;this.score = score;}@Overridepublic String toString() {return "[" + this.name + ":" + this.score + "]";}// Getter方法用于访问私有字段public String getName() { return name; }public int getScore() { return score; }
}public class Test {public static void main(String[] args) {Student[] students = new Student[] {new Student("张三", 95),new Student("李四", 96),new Student("王五", 97),new Student("赵六", 92),};// 使用Comparator实现降序排序Comparator<Student> scoreComparator = Comparator.comparingInt(Student::getScore).reversed();// 传入Comparator进行排序Arrays.sort(students, scoreComparator);System.out.println(Arrays.toString(students));}
}

在这里插入图片描述

  • Student::getScore 是一种简洁的函数式语法,等价于 lambda 表达式(Student s) -> s.getScore()
  • 由于 getScore() 返回 int,符合 ToIntFunction 接口的要求。

总结

  1. Comparable让类自身实现排序规则,适用于类的默认排序逻辑;Comparator在外部定义排序规则,不修改原类。可通过 Lambda 简化实现。适用于临时排序或多种排序方式。
  2. Comparable 是通过重写 compareTo 方法实现排序的,而 Comparator 是通过重写 compare 方法实现排序的
  3. 侵入性:实现Comparable接口会对类产生侵入,因为要修改类的定义;实现Comparator接口则不会影响类的定义,能在不修改类的情况下实现不同的排序规则。
  4. 使用灵活性:Comparable接口只能有一种自然排序规则;Comparator接口可以创建多个不同的比较器,实现多种排序规则。
http://www.xdnf.cn/news/12024.html

相关文章:

  • React-native实战系列
  • 每日算法-250604
  • Sui Prover:将形式化验证引入 Sui
  • yFiles:专业级图可视化终极解决方案
  • 2025年6月4日第一轮
  • Unity大型项目资源框架
  • 运行labelme
  • 【C/C++】析构函数好玩的用法:~Derived() override
  • day44python打卡
  • AI 基础应用与提示词工程
  • 深入理解计算机进制:从原理到 C++ 实现
  • WireShark相关技巧
  • 根据重叠点云生成匹配图像之间的对应点对
  • 【二分图 图论】P9384 [THUPC 2023 决赛] 着色|普及+
  • AI数字人软件开发:赋能企业数字化转型,打造智能服务新标杆
  • c#压缩与解压缩-SharpCompress
  • MySQL EXPLAIN 命令详解
  • 为什么选择电商平台API接口服务商?
  • 剑指offer16_在O(1)时间删除链表结点
  • Google AI 模式下的SEO革命:生成式搜索优化(GEO)与未来营销策略
  • 假票入账会怎样?
  • 沉金电路板有哪些特点?
  • JDK 8 到 JDK 24 新特性大全
  • [3-02-01].第13节:三方整合 - Jedis客户端操作Redis
  • 基于VMD-LSTM融合方法的F10.7指数预报
  • return this;返回的是谁
  • 遍历继承QObject的对象的属性
  • macOS 连接 Docker 运行 postgres,使用navicat添加并关联数据库
  • Inno Setup 脚本中常用术语释义
  • Python中库的安装使用过程详解