Java(十二)——Comparable接口与Comparator接口
文章目录
- Comparable与Comparator接口
- Comparable接口
- Comparator接口
Comparable与Comparator接口
我们可能会遇到这样的问题:怎么对一个对象数组进行排序? 比如对一个狗类对象数组进行排序,而想到这,我们又会有一个问题:怎么比较两个对象?如果我想自定义标准,怎么办?
与基本类型的比较并排序不同,对象数组没有一个统一的标准来进行比较来排序,此时就可以基于Comparable接口实现或者基于比较器实现(Comparator接口)
- 自然排序:基于Comparable接口
- 定制排序:基于Comparator接口
本文均以自定义的Person类为例:
public class Person {private String name;private int age;public Person(String name, int age) {this.name = name;this.age = age;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}@Overridepublic String toString() {return "Person{" +"name='" + name + '\'' +", age=" + age +'}';}}
Comparable接口
使用了Comparable接口,意味着此类可排序,使用方法是:在想要实现比较的类中实现Comparable接口并重写compareTo()方法
我们先观察一下Comparable接口的源码:

我们发现,Comparable接口中只有一个CompareTo方法
观察完毕后,我们看如下实现代码:
//Person.java
//实现Comparable接口
public class Person implements Comparable<Person> {private String name;private int age;public Person(String name, int age) {this.name = name;this.age = age;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}@Overridepublic String toString() {return "Person{" +"name='" + name + '\'' +", age=" + age +'}';}//重写compareTo方法,这里按照name(字符串)比较@Overridepublic int compareTo(Person o) {if(this.name.compareTo(o.name) > 0) {return 1;}else if(this.name.compareTo(o.name) < 0) {return -1;}else {return 0;}}
}//Test.java
import java.util.Arrays;public class Test {public static void main(String[] args) {Person[] people = new Person[]{new Person("zhangsan", 23), new Person("lisi", 15),new Person("wangwu", 42)};//实现了Comparable接口后,可以通过Arrays类中的排序方法给对象数组排序了Arrays.sort(people);for(Person p : people) {System.out.println(p);}}
}
打印结果如下:

-
Comparable接口后面的<>是泛型知识,传入要比较的类即可 -
实现
Comparable接口必须重写CompareTo方法,方法要求返回int类型的值,一般内部实现的逻辑:调用方法的对象 > 作为参数的对象,返回正数;调用方法的对象 < 作为参数的对象,返回负数;调用方法的对象 == 作为参数的对象,返回0
-
一个类实现了
Comparable接口,那么就可以调用Arrays类中的sort方法对存放此类对象的数组进行排序 -
一个实现了
Comparable接口的类只能重写一个compareTo方法,这也意味着标准被固定
Comparator接口
前面提到,基于Comparable接口实现比较的标准固定,且不便在原代码修改,这种情况下,我们可以通过Comparator接口(比较器)实现,方法是:定义一个或多个比较器类,实现Comparator接口,并重写Compare方法
我们先观察一下Comparator接口的一部分源码:

这部分源码显示,Comparator接口中包含compare和equals方法,实现了Comparator接口的类可以不重写equals方法,但是一定要重写compare方法
观察完毕后,我们看如下实现代码:
//Person.java
public class Person {private String name;private int age;public Person(String name, int age) {this.name = name;this.age = age;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}@Overridepublic String toString() {return "Person{" +"name='" + name + '\'' +", age=" + age +'}';}}//AgeComparator.java
//以年龄比较的比较器
import java.util.Comparator;public class AgeComparator implements Comparator<Person> {@Overridepublic int compare(Person o1, Person o2) {return o1.getAge() - o2.getAge();}
}//NameComparator.java
//以名字比较的比较器
import java.util.Comparator;public class NameComparator implements Comparator<Person> {@Overridepublic int compare(Person o1, Person o2) {return o1.getName().compareTo(o2.getName());}
}//Test.java
import java.util.Arrays;public class Test {public static void main(String[] args) {Person[] people = new Person[]{new Person("zhangsan", 23), new Person("lisi", 15),new Person("wangwu", 42)};//使用时,必须实例化比较器对象AgeComparator ageComparator = new AgeComparator();NameComparator nameComparator = new NameComparator();//正常使用System.out.println(ageComparator.compare(new Person("张三", 16), new Person("李四", 10)));//与Arrays类中的sort方法配合使用Arrays.sort(people, ageComparator);for(Person p : people) {System.out.println(p);}}
}
打印结果如下:

- 要比较的对象的类不需要实现
Comparator接口,比较器需要实现Comparator接口,并在<>内给出要比较的类,并重写compare方法 - 重写的
compare方法有两个参数,分别是要比较的两个对象,重写的compare方法要求:返回值的正负以及零,表示不同的比较结果。例如,左参数对象大于右参数对象,返回正值;左参数对象小于右参数对象,返回负值;左右参数对象相等,返回0 - 使用时,必须实例化比较器类对象。可以选择直接调用其中的
compare方法比较单一对象,也可以配合Arrays类中的sort方法对对象数组进行排序,此时sort方法需要两个参数:1. 对象数组 2. 比较器对象 - 比较器可以创建若干个,意味着我们可以定义多个标准,相对灵活一些
区别:
Comparable相当于 “内部比较器”,Comparator相当于 “外部比较器”- 对于基于
Comparable的比较,需要手动实现接口,侵入性比较强,但一旦实现,每次调用该类都有顺序,属于内部顺序- 对于基于
Comparator的比较,需要实现一个比较器对象,对待比较类的侵入性弱,但对算法代码实现侵入性强
侵入性:让用户代码产生对框架的依赖,这些代码不能直接脱离框架使用,不利于代码的复用
关于对象的比较,数据结构部分会经常用到
我们的SE部分的补充知识到此结束了,小裤马上会发一篇SE语法合集
相关文章:
Java(十二)——Comparable接口与Comparator接口
文章目录 Comparable与Comparator接口Comparable接口Comparator接口 Comparable与Comparator接口 我们可能会遇到这样的问题:怎么对一个对象数组进行排序? 比如对一个狗类对象数组进行排序,而想到这,我们又会有一个问题ÿ…...
Nvidia Jetson/Orin +FPGA+AI大算力边缘计算盒子:轨道交通监控系统
株洲中车时代电气股份有限公司(下称中车时代电气)是中国中车旗下股份制企业,其前身及母公司——中车株洲电力机车研究所有限公司创立于1959年。中车时代电气扎根株洲,走好两条钢轨,走出两条钢轨。中车时代电气秉承“双…...
笔记 | 软件工程01:从程序到软件
1 软件工程知识域 2 程序 2.1 何为程序及程序的质量要求 何为程序: 理解:软件工程可能就是在弥补OOP语言与自然语言之间还存在的鸿沟 2.1.1 程序质量的内在和外在体现 2.1.2 程序质量的语法和语义体现 2.2 编写代码的基本原则 2.3 程序质量保证方法 …...
废品回收小程序开发,助力商家拓展回收市场
随着互联网的快速发展,废品回收行业也走向了数字化发展,废品回收小程序成为了拓展市场的重要方式。在当下万亿元下的回收市场中,废品回收小程序的发展也能够发挥重要作用,提高市场回收效率,提高大众的回收意识…...
JVM类加载机制和双亲委派
类加载机制 java文件需要编译成字节码文件(.class文件),jvm是通过类加载机制,将.class文件加载进内存,经过验证连接->初始化直到使用该对象的过程就是类加载机制,当new对象的时候,jvm首先去常量池寻找该类的符号引用…...
【PyCharm】无法创建虚拟环境,提示:has no attribute CPython3macOsBrew
报错信息: AttributeError: module virtualenv.create.via_global_ref.builtin.cpython.mac_os has no attribute CPython3macOsBrew报错原因: 可能含有多个virtualenv,发生冲突了。 解决方法: 终端执行以下命令: p…...
华为OD刷题C卷 - 每日刷题 12(数组连续和,求最多可以派出多少支团队)
1、(数组连续和): 这段代码是解决“数组连续和”的问题。它提供了一个Java类Main,其中包含main方法和getResult方法,用于计算给定数组中有多少个连续区间的和大于等于给定值x。 main方法首先读取数组的长度n和阈值x&…...
2.1 初识Windows程序
Windows程序设计是一种面向对象的编程。Windows操作系统以数据结构的形式定义了大量预定义的对象作为操作系统的数据类型。Windows动态链接库提供了各种各样的API接口函数供Windows应用程序调用。一个Windows应用程序是运行在Windows操作系统之上的。这些API接口函数的调用所实…...
EDI系统的使用场景
EDI全称Electronic Data Interchange,中文名称是电子数据交换。EDI系统是专为企业间的电子数据传输而设计的,需要满足的基本功能包括:支持AS2、OFTP、SFTP等EDI传输协议,能够生成和解析符合X12、EDIFACT、VDA等EDI报文标准下的报文…...
韩国Neowine推出第三代强加密芯片ALPU-CV
推出第三代加密芯片;是ALPU系列中的高端IC;是一款高性能车规级加密芯片;其加密性更强、低耗电、体积小;使得防复制、防抄袭板子的加密性能大大提升,该芯片通过《AEC-Q100》认证,目前已经在国产前装车辆配件…...
golang结构与接口方法实现与交互使用示例
1.定义结构 // 结构定义 type VideoFrame struct {id inthead []bytelen int64data []byte } 2.实现结构方法 // 生成结构字段的get与set方法 // func (v *VideoFrame) Id() int {return v.id }func (v *VideoFrame) SetId(id int) {v.id id }func (v *VideoFrame) He…...
C# 判断字符串不等于空的示例
在C#中,要判断一个字符串是否不等于空(即它既不是null也不是空字符串""),方法有如下几种,如下。 方法1 使用逻辑运算符和string.IsNullOrEmpty方法 string myString "123"; // 假设要检查的字…...
直方图中最大的矩形
#include<iostream> #include<algorithm> using namespace std; const int N 100010; //l[i], r[i]表示第i个矩形的高度可向两侧扩展的左右边界 int h[N], q[N], l[N], r[N]; typedef long long LL; int main() { int n; while(scanf("%d"…...
分布式锁redisson
1:pom.xml添加依赖 <dependency><groupId>org.redisson</groupId><artifactId>redisson-spring-boot-starter</artifactId><version>3.21.1</version> </dependency>2-1:方法一:读取默认ym…...
将小爱音箱接入 ChatGPT 和豆包ai改造成专属语音助手
这个GitHub项目,mi-gpt,旨在将小爱音箱和米家设备与ChatGPT和豆包集成,有效地将这些设备转变为个性化语音助手。以下是对其功能和设置的详细分析: 主要特点 角色扮演:该项目允许小爱适应不同的角色,如伴侣…...
短网址生成原理及使用
生成短网址介绍: 一、定义 短网址(Short URL)是形式上比较短的网址,它通过将原始冗长的网址进行缩短,方便用户分享和记忆。短网址的生成主要依赖于特定的算法和服务,通过后端服务转向来实现网址的缩短。 …...
C#调用word组件转pdf,遇到视图保护解决方法
由于我们在自己项目里常常要调用office组件将word另存pdf格式,但是常遇到用户上传的word视图保护, 组件不能正常打开word而导致不能有效转pdf(原因是文件被WPS编辑过),困扰很长时间,各种方法用过如用第三方组件替换office组件&…...
NAT端口映射,实现外网访问内网服务器
目录 前言一、搭建网络拓扑1.1 配置server和pc1.1.1 配置server01.1.2 配置server11.1.3 配置pc0 1.2 配置客户路由器1.2.1 配置路由器IP1.2.2 配置静态路由 1.3 配置ISP路由器 二、配置端口映射2.1 在客户路由器配置端口映射2.2 测试公网计算机访问私网服务器2.2.1 PC0向serve…...
【面试笔记】嵌入式软件工程师,汽车电子软件相关
文章目录 1. C语言基础1.1 const1.2 static1.3 回调函数的用法1.4 宏定义1.5 编译、链接过程1.6 堆与栈的区别?1.7 简单的字符串算法题,C语言实现1.7.1 给定一个字符串,按顺序筛选出不重复的字符组成字符串,输出该字符串1.7.2 给定…...
uniapp小程序开发 | 从零实现一款影视类app (后台接口实现,go-zero微服务的使用)
uniapp小程序开发实战系列,完整介绍从零实现一款影视类小程序。包含小程序前端和后台接口的全部完整实现。系列连载中,喜欢的可以点击收藏。 该篇着重介绍获取轮播图后台接口和获取正在热映电影的两个后台接口的实现。 后台服务使用golang,…...
浏览器访问 AWS ECS 上部署的 Docker 容器(监听 80 端口)
✅ 一、ECS 服务配置 Dockerfile 确保监听 80 端口 EXPOSE 80 CMD ["nginx", "-g", "daemon off;"]或 EXPOSE 80 CMD ["python3", "-m", "http.server", "80"]任务定义(Task Definition&…...
前端倒计时误差!
提示:记录工作中遇到的需求及解决办法 文章目录 前言一、误差从何而来?二、五大解决方案1. 动态校准法(基础版)2. Web Worker 计时3. 服务器时间同步4. Performance API 高精度计时5. 页面可见性API优化三、生产环境最佳实践四、终极解决方案架构前言 前几天听说公司某个项…...
深入理解JavaScript设计模式之单例模式
目录 什么是单例模式为什么需要单例模式常见应用场景包括 单例模式实现透明单例模式实现不透明单例模式用代理实现单例模式javaScript中的单例模式使用命名空间使用闭包封装私有变量 惰性单例通用的惰性单例 结语 什么是单例模式 单例模式(Singleton Pattern&#…...
OkHttp 中实现断点续传 demo
在 OkHttp 中实现断点续传主要通过以下步骤完成,核心是利用 HTTP 协议的 Range 请求头指定下载范围: 实现原理 Range 请求头:向服务器请求文件的特定字节范围(如 Range: bytes1024-) 本地文件记录:保存已…...
dify打造数据可视化图表
一、概述 在日常工作和学习中,我们经常需要和数据打交道。无论是分析报告、项目展示,还是简单的数据洞察,一个清晰直观的图表,往往能胜过千言万语。 一款能让数据可视化变得超级简单的 MCP Server,由蚂蚁集团 AntV 团队…...
深度学习习题2
1.如果增加神经网络的宽度,精确度会增加到一个特定阈值后,便开始降低。造成这一现象的可能原因是什么? A、即使增加卷积核的数量,只有少部分的核会被用作预测 B、当卷积核数量增加时,神经网络的预测能力会降低 C、当卷…...
基于Java+MySQL实现(GUI)客户管理系统
客户资料管理系统的设计与实现 第一章 需求分析 1.1 需求总体介绍 本项目为了方便维护客户信息为了方便维护客户信息,对客户进行统一管理,可以把所有客户信息录入系统,进行维护和统计功能。可通过文件的方式保存相关录入数据,对…...
2025年渗透测试面试题总结-腾讯[实习]科恩实验室-安全工程师(题目+回答)
安全领域各种资源,学习文档,以及工具分享、前沿信息分享、POC、EXP分享。不定期分享各种好玩的项目及好用的工具,欢迎关注。 目录 腾讯[实习]科恩实验室-安全工程师 一、网络与协议 1. TCP三次握手 2. SYN扫描原理 3. HTTPS证书机制 二…...
Golang——9、反射和文件操作
反射和文件操作 1、反射1.1、reflect.TypeOf()获取任意值的类型对象1.2、reflect.ValueOf()1.3、结构体反射 2、文件操作2.1、os.Open()打开文件2.2、方式一:使用Read()读取文件2.3、方式二:bufio读取文件2.4、方式三:os.ReadFile读取2.5、写…...
第7篇:中间件全链路监控与 SQL 性能分析实践
7.1 章节导读 在构建数据库中间件的过程中,可观测性 和 性能分析 是保障系统稳定性与可维护性的核心能力。 特别是在复杂分布式场景中,必须做到: 🔍 追踪每一条 SQL 的生命周期(从入口到数据库执行)&#…...
