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

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.lqws.cn/news/130087.html

相关文章:

  • 腾讯位置商业授权AOI边界查询开发指南
  • 【PmHub面试篇】PmHub 整合 TransmittableThreadLocal(TTL)缓存用户数据面试专题解析
  • 《胸椎后路切开复位内固定术风险管控标准化路径:MDT协作下的三级预防策略》 ——基于生物力学重建、智能预警系统与快速康复的整合方案
  • DINO-R1
  • 在本地电脑中部署阿里 Qwen3 大模型及连接到 Elasticsearch
  • 机器学习14-迁移学习
  • go语言的锁
  • 机器学习:聚类算法
  • golang常用库之-go-feature-flag库(特性开关(Feature Flags))
  • AI数字人软件开发:赋能企业数字化转型,打造智能服务新标杆
  • 跟着顶刊学配色 | 第 1~4 期
  • 中断、MsTimer2、Ticker、多任务功能详解
  • 麒麟+ARM架构安装mysql8的操作指南
  • 大数据分析07 数据链接
  • 第 86 场周赛:矩阵中的幻方、钥匙和房间、将数组拆分成斐波那契序列、猜猜这个单词
  • Shopify 主题开发:促销活动页面专属设计思路
  • 告别延迟,拥抱速度:存储加速仿真应用的解决方案【1】
  • DexUMI:以人手为通用操作界面,实现灵巧操作
  • 激活函数和归一化、正则化
  • Unstructured.io 文件 Extract 方案概述
  • redis集群和哨兵的区别
  • MySQL 索引:为使用 B+树作为索引数据结构,而非 B树、哈希表或二叉树?
  • Python 解释器安装全攻略(适用于 Linux / Windows / macOS)
  • Spring AI 项目实战(五):Spring Boot + AI + DeepSeek + Redis 实现聊天应用上下文记忆功能(附完整源码)
  • VR博物馆推动现代数字化科技博物馆
  • 基于 ShardingSphere + Seata 的最终一致性事务完整示例实现
  • 思维力三阶 · 序章:从认知碎片到系统思维——点亮内心的“认知操作系统”蓝图
  • 佰力博科技与您探讨半导体电阻测试的基本原理
  • UE5 创建了一个C++类,现在我还有一个蓝图类,我想将编写的C++类中包含的功能加入到这个蓝图类里面,如何做到
  • Redis中的setIfAbsent方法和execute