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

Java(十二)——Comparable接口与Comparator接口

文章目录

  • Comparable与Comparator接口
    • Comparable接口
    • Comparator接口

Comparable与Comparator接口

我们可能会遇到这样的问题:怎么对一个对象数组进行排序? 比如对一个狗类对象数组进行排序,而想到这,我们又会有一个问题:怎么比较两个对象?如果我想自定义标准,怎么办?

与基本类型的比较并排序不同,对象数组没有一个统一的标准来进行比较来排序,此时就可以基于Comparable接口实现或者基于比较器实现(Comparator接口)

  1. 自然排序:基于Comparable接口
  2. 定制排序:基于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接口中包含compareequals方法,实现了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. 比较器对象
  • 比较器可以创建若干个,意味着我们可以定义多个标准,相对灵活一些

区别:

  1. Comparable 相当于 “内部比较器”,Comparator相当于 “外部比较器”
  2. 对于基于Comparable的比较,需要手动实现接口,侵入性比较强,但一旦实现,每次调用该类都有顺序,属于内部顺序
  3. 对于基于Comparator的比较,需要实现一个比较器对象,对待比较类的侵入性弱,但对算法代码实现侵入性强

侵入性:让用户代码产生对框架的依赖,这些代码不能直接脱离框架使用,不利于代码的复用

关于对象的比较,数据结构部分会经常用到


我们的SE部分的补充知识到此结束了,小裤马上会发一篇SE语法合集

相关文章:

Java(十二)——Comparable接口与Comparator接口

文章目录 Comparable与Comparator接口Comparable接口Comparator接口 Comparable与Comparator接口 我们可能会遇到这样的问题&#xff1a;怎么对一个对象数组进行排序&#xff1f; 比如对一个狗类对象数组进行排序&#xff0c;而想到这&#xff0c;我们又会有一个问题&#xff…...

Nvidia Jetson/Orin +FPGA+AI大算力边缘计算盒子:轨道交通监控系统

株洲中车时代电气股份有限公司&#xff08;下称中车时代电气&#xff09;是中国中车旗下股份制企业&#xff0c;其前身及母公司——中车株洲电力机车研究所有限公司创立于1959年。中车时代电气扎根株洲&#xff0c;走好两条钢轨&#xff0c;走出两条钢轨。中车时代电气秉承“双…...

笔记 | 软件工程01:从程序到软件

1 软件工程知识域 2 程序 2.1 何为程序及程序的质量要求 何为程序&#xff1a; 理解&#xff1a;软件工程可能就是在弥补OOP语言与自然语言之间还存在的鸿沟 2.1.1 程序质量的内在和外在体现 2.1.2 程序质量的语法和语义体现 2.2 编写代码的基本原则 2.3 程序质量保证方法 …...

废品回收小程序开发,助力商家拓展回收市场

随着互联网的快速发展&#xff0c;废品回收行业也走向了数字化发展&#xff0c;废品回收小程序成为了拓展市场的重要方式。在当下万亿元下的回收市场中&#xff0c;废品回收小程序的发展也能够发挥重要作用&#xff0c;提高市场回收效率&#xff0c;提高大众的回收意识&#xf…...

JVM类加载机制和双亲委派

类加载机制 java文件需要编译成字节码文件(.class文件)&#xff0c;jvm是通过类加载机制&#xff0c;将.class文件加载进内存&#xff0c;经过验证连接->初始化直到使用该对象的过程就是类加载机制&#xff0c;当new对象的时候&#xff0c;jvm首先去常量池寻找该类的符号引用…...

【PyCharm】无法创建虚拟环境,提示:has no attribute CPython3macOsBrew

报错信息&#xff1a; AttributeError: module virtualenv.create.via_global_ref.builtin.cpython.mac_os has no attribute CPython3macOsBrew报错原因&#xff1a; 可能含有多个virtualenv&#xff0c;发生冲突了。 解决方法&#xff1a; 终端执行以下命令&#xff1a; p…...

华为OD刷题C卷 - 每日刷题 12(数组连续和,求最多可以派出多少支团队)

1、&#xff08;数组连续和&#xff09;&#xff1a; 这段代码是解决“数组连续和”的问题。它提供了一个Java类Main&#xff0c;其中包含main方法和getResult方法&#xff0c;用于计算给定数组中有多少个连续区间的和大于等于给定值x。 main方法首先读取数组的长度n和阈值x&…...

2.1 初识Windows程序

Windows程序设计是一种面向对象的编程。Windows操作系统以数据结构的形式定义了大量预定义的对象作为操作系统的数据类型。Windows动态链接库提供了各种各样的API接口函数供Windows应用程序调用。一个Windows应用程序是运行在Windows操作系统之上的。这些API接口函数的调用所实…...

EDI系统的使用场景

EDI全称Electronic Data Interchange&#xff0c;中文名称是电子数据交换。EDI系统是专为企业间的电子数据传输而设计的&#xff0c;需要满足的基本功能包括&#xff1a;支持AS2、OFTP、SFTP等EDI传输协议&#xff0c;能够生成和解析符合X12、EDIFACT、VDA等EDI报文标准下的报文…...

韩国Neowine推出第三代强加密芯片ALPU-CV

推出第三代加密芯片&#xff1b;是ALPU系列中的高端IC&#xff1b;是一款高性能车规级加密芯片&#xff1b;其加密性更强、低耗电、体积小&#xff1b;使得防复制、防抄袭板子的加密性能大大提升&#xff0c;该芯片通过《AEC-Q100》认证&#xff0c;目前已经在国产前装车辆配件…...

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#中&#xff0c;要判断一个字符串是否不等于空&#xff08;即它既不是null也不是空字符串""&#xff09;&#xff0c;方法有如下几种&#xff0c;如下。 方法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&#xff1a;pom.xml添加依赖 <dependency><groupId>org.redisson</groupId><artifactId>redisson-spring-boot-starter</artifactId><version>3.21.1</version> </dependency>2-1&#xff1a;方法一&#xff1a;读取默认ym…...

将小爱音箱接入 ChatGPT 和豆包ai改造成专属语音助手

这个GitHub项目&#xff0c;mi-gpt&#xff0c;旨在将小爱音箱和米家设备与ChatGPT和豆包集成&#xff0c;有效地将这些设备转变为个性化语音助手。以下是对其功能和设置的详细分析&#xff1a; 主要特点 角色扮演&#xff1a;该项目允许小爱适应不同的角色&#xff0c;如伴侣…...

短网址生成原理及使用

生成短网址介绍&#xff1a; 一、定义 短网址&#xff08;Short URL&#xff09;是形式上比较短的网址&#xff0c;它通过将原始冗长的网址进行缩短&#xff0c;方便用户分享和记忆。短网址的生成主要依赖于特定的算法和服务&#xff0c;通过后端服务转向来实现网址的缩短。 …...

C#调用word组件转pdf,遇到视图保护解决方法

由于我们在自己项目里常常要调用office组件将word另存pdf格式&#xff0c;但是常遇到用户上传的word视图保护&#xff0c; 组件不能正常打开word而导致不能有效转pdf(原因是文件被WPS编辑过)&#xff0c;困扰很长时间&#xff0c;各种方法用过如用第三方组件替换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 堆与栈的区别&#xff1f;1.7 简单的字符串算法题&#xff0c;C语言实现1.7.1 给定一个字符串&#xff0c;按顺序筛选出不重复的字符组成字符串&#xff0c;输出该字符串1.7.2 给定…...

uniapp小程序开发 | 从零实现一款影视类app (后台接口实现,go-zero微服务的使用)

uniapp小程序开发实战系列&#xff0c;完整介绍从零实现一款影视类小程序。包含小程序前端和后台接口的全部完整实现。系列连载中&#xff0c;喜欢的可以点击收藏。 该篇着重介绍获取轮播图后台接口和获取正在热映电影的两个后台接口的实现。 后台服务使用golang&#xff0c;…...

第19节 Node.js Express 框架

Express 是一个为Node.js设计的web开发框架&#xff0c;它基于nodejs平台。 Express 简介 Express是一个简洁而灵活的node.js Web应用框架, 提供了一系列强大特性帮助你创建各种Web应用&#xff0c;和丰富的HTTP工具。 使用Express可以快速地搭建一个完整功能的网站。 Expre…...

黑马Mybatis

Mybatis 表现层&#xff1a;页面展示 业务层&#xff1a;逻辑处理 持久层&#xff1a;持久数据化保存 在这里插入图片描述 Mybatis快速入门 ![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/6501c2109c4442118ceb6014725e48e4.png //logback.xml <?xml ver…...

vscode(仍待补充)

写于2025 6.9 主包将加入vscode这个更权威的圈子 vscode的基本使用 侧边栏 vscode还能连接ssh&#xff1f; debug时使用的launch文件 1.task.json {"tasks": [{"type": "cppbuild","label": "C/C: gcc.exe 生成活动文件"…...

大语言模型如何处理长文本?常用文本分割技术详解

为什么需要文本分割? 引言:为什么需要文本分割?一、基础文本分割方法1. 按段落分割(Paragraph Splitting)2. 按句子分割(Sentence Splitting)二、高级文本分割策略3. 重叠分割(Sliding Window)4. 递归分割(Recursive Splitting)三、生产级工具推荐5. 使用LangChain的…...

C++.OpenGL (10/64)基础光照(Basic Lighting)

基础光照(Basic Lighting) 冯氏光照模型(Phong Lighting Model) #mermaid-svg-GLdskXwWINxNGHso {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-GLdskXwWINxNGHso .error-icon{fill:#552222;}#mermaid-svg-GLd…...

html css js网页制作成品——HTML+CSS榴莲商城网页设计(4页)附源码

目录 一、&#x1f468;‍&#x1f393;网站题目 二、✍️网站描述 三、&#x1f4da;网站介绍 四、&#x1f310;网站效果 五、&#x1fa93; 代码实现 &#x1f9f1;HTML 六、&#x1f947; 如何让学习不再盲目 七、&#x1f381;更多干货 一、&#x1f468;‍&#x1f…...

【Nginx】使用 Nginx+Lua 实现基于 IP 的访问频率限制

使用 NginxLua 实现基于 IP 的访问频率限制 在高并发场景下&#xff0c;限制某个 IP 的访问频率是非常重要的&#xff0c;可以有效防止恶意攻击或错误配置导致的服务宕机。以下是一个详细的实现方案&#xff0c;使用 Nginx 和 Lua 脚本结合 Redis 来实现基于 IP 的访问频率限制…...

BLEU评分:机器翻译质量评估的黄金标准

BLEU评分&#xff1a;机器翻译质量评估的黄金标准 1. 引言 在自然语言处理(NLP)领域&#xff0c;衡量一个机器翻译模型的性能至关重要。BLEU (Bilingual Evaluation Understudy) 作为一种自动化评估指标&#xff0c;自2002年由IBM的Kishore Papineni等人提出以来&#xff0c;…...

论文阅读笔记——Muffin: Testing Deep Learning Libraries via Neural Architecture Fuzzing

Muffin 论文 现有方法 CRADLE 和 LEMON&#xff0c;依赖模型推理阶段输出进行差分测试&#xff0c;但在训练阶段是不可行的&#xff0c;因为训练阶段直到最后才有固定输出&#xff0c;中间过程是不断变化的。API 库覆盖低&#xff0c;因为各个 API 都是在各种具体场景下使用。…...

嵌入式常见 CPU 架构

架构类型架构厂商芯片厂商典型芯片特点与应用场景PICRISC (8/16 位)MicrochipMicrochipPIC16F877A、PIC18F4550简化指令集&#xff0c;单周期执行&#xff1b;低功耗、CIP 独立外设&#xff1b;用于家电、小电机控制、安防面板等嵌入式场景8051CISC (8 位)Intel&#xff08;原始…...