当前位置: 首页 > 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;…...

地震勘探——干扰波识别、井中地震时距曲线特点

目录 干扰波识别反射波地震勘探的干扰波 井中地震时距曲线特点 干扰波识别 有效波&#xff1a;可以用来解决所提出的地质任务的波&#xff1b;干扰波&#xff1a;所有妨碍辨认、追踪有效波的其他波。 地震勘探中&#xff0c;有效波和干扰波是相对的。例如&#xff0c;在反射波…...

椭圆曲线密码学(ECC)

一、ECC算法概述 椭圆曲线密码学&#xff08;Elliptic Curve Cryptography&#xff09;是基于椭圆曲线数学理论的公钥密码系统&#xff0c;由Neal Koblitz和Victor Miller在1985年独立提出。相比RSA&#xff0c;ECC在相同安全强度下密钥更短&#xff08;256位ECC ≈ 3072位RSA…...

以下是对华为 HarmonyOS NETX 5属性动画(ArkTS)文档的结构化整理,通过层级标题、表格和代码块提升可读性:

一、属性动画概述NETX 作用&#xff1a;实现组件通用属性的渐变过渡效果&#xff0c;提升用户体验。支持属性&#xff1a;width、height、backgroundColor、opacity、scale、rotate、translate等。注意事项&#xff1a; 布局类属性&#xff08;如宽高&#xff09;变化时&#…...

镜像里切换为普通用户

如果你登录远程虚拟机默认就是 root 用户&#xff0c;但你不希望用 root 权限运行 ns-3&#xff08;这是对的&#xff0c;ns3 工具会拒绝 root&#xff09;&#xff0c;你可以按以下方法创建一个 非 root 用户账号 并切换到它运行 ns-3。 一次性解决方案&#xff1a;创建非 roo…...

爬虫基础学习day2

# 爬虫设计领域 工商&#xff1a;企查查、天眼查短视频&#xff1a;抖音、快手、西瓜 ---> 飞瓜电商&#xff1a;京东、淘宝、聚美优品、亚马逊 ---> 分析店铺经营决策标题、排名航空&#xff1a;抓取所有航空公司价格 ---> 去哪儿自媒体&#xff1a;采集自媒体数据进…...

【论文阅读28】-CNN-BiLSTM-Attention-(2024)

本文把滑坡位移序列拆开、筛优质因子&#xff0c;再用 CNN-BiLSTM-Attention 来动态预测每个子序列&#xff0c;最后重构出总位移&#xff0c;预测效果超越传统模型。 文章目录 1 引言2 方法2.1 位移时间序列加性模型2.2 变分模态分解 (VMD) 具体步骤2.3.1 样本熵&#xff08;S…...

Java多线程实现之Thread类深度解析

Java多线程实现之Thread类深度解析 一、多线程基础概念1.1 什么是线程1.2 多线程的优势1.3 Java多线程模型 二、Thread类的基本结构与构造函数2.1 Thread类的继承关系2.2 构造函数 三、创建和启动线程3.1 继承Thread类创建线程3.2 实现Runnable接口创建线程 四、Thread类的核心…...

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

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

C++:多态机制详解

目录 一. 多态的概念 1.静态多态&#xff08;编译时多态&#xff09; 二.动态多态的定义及实现 1.多态的构成条件 2.虚函数 3.虚函数的重写/覆盖 4.虚函数重写的一些其他问题 1&#xff09;.协变 2&#xff09;.析构函数的重写 5.override 和 final关键字 1&#…...

在 Spring Boot 项目里,MYSQL中json类型字段使用

前言&#xff1a; 因为程序特殊需求导致&#xff0c;需要mysql数据库存储json类型数据&#xff0c;因此记录一下使用流程 1.java实体中新增字段 private List<User> users 2.增加mybatis-plus注解 TableField(typeHandler FastjsonTypeHandler.class) private Lis…...