Java-----Comparable接口和Comparator接口
在Java中,我们会经常使用到自定义类,那我们如何进行自定义类的比较呢?
1.Comparable接口
普通数据的比较
int a=10;int b=91;System.out.println(a<b);
那自定义类型可不可以这样比较呢?看一下代码

我们发现会报错,因为自定义类型,stu1和stu2里面存的是引用,是无法直接根据姓名或年龄进行比较的。
1.1Comparable接口的使用
如果想要自定义类型根据年龄和名字进行比较,这时候就要用到我们的Comparable接口。

当我们观察Comparable接口的底层细节会发现有一个<T>和一个方法,<T>代表我们要比较的类型,方法是我们根据实际情况来重写compareTo方法,也就是比较的规则。
1.根据年龄比较
自定义类中具体实现
class Student implements Comparable<Student>{public String name;public int age;public Student(String name, int age) {this.name = name;this.age = age;}@Overridepublic int compareTo(Student o) {//根据年龄比较/*if(this.age>o.age){return 1;}else if (this.age==o.age){return 0;}else {return -1;}*/return this.age-o.age;}
}
完整代码
class Student implements Comparable<Student>{public String name;public int age;public Student(String name, int age) {this.name = name;this.age = age;}@Overridepublic int compareTo(Student o) {//根据年龄比较/*if(this.age>o.age){return 1;}else if (this.age==o.age){return 0;}else {return -1;}*/return this.age-o.age;}
}
public class Test {public static void main(String[] args) {Student stu1=new Student("zhansan",18);Student stu2=new Student("man",24);System.out.println(stu1.compareTo(stu2));}
}
2.根据名字比较
class Student implements Comparable<Student>{public String name;public int age;public Student(String name, int age) {this.name = name;this.age = age;}@Overridepublic int compareTo(Student o) {return this.name.compareTo(o.name);}
}
public class Test {public static void main(String[] args) {Student stu1=new Student("zhansan",18);Student stu2=new Student("man",24);System.out.println(stu1.compareTo(stu2));}
}
由于名字是String类,String类在底层中也实现了compareTo方法,所以我们可以直接调用compareTo方法来实现名字的比较。
3. 多个对象之间的比较
多个对象我们可以用一个对应类的数组来存储,然后思路就是让数组里面的元素就行比较。
这里模拟了冒泡排序进行比较。
根据名字来排序
import java.util.Arrays;class Student implements Comparable<Student>{public String name;public int age;public Student(String name, int age) {this.name = name;this.age = age;}@Overridepublic String toString() {return "Student{" +"name='" + name + '\'' +", age=" + age +'}';}@Overridepublic int compareTo(Student o) {return this.name.compareTo(o.name);}
}
public class Test {public static void mysort(Comparable[] comparables){for (int i = 0; i < comparables.length-1; i++) {for(int j=0;j<comparables.length-1-i;j++){if(comparables[j].compareTo(comparables[j+1])>0){Comparable tmp=comparables[j];comparables[j]=comparables[j+1];comparables[j+1]=tmp;}}}}public static void main(String[] args) {Student[] students=new Student[]{new Student("zhansan",18),new Student("man",24),new Student("lebron",23)};mysort(students);System.out.println(Arrays.toString(students));}
}

根据年龄来排序
import java.util.Arrays;class Student implements Comparable<Student>{public String name;public int age;public Student(String name, int age) {this.name = name;this.age = age;}@Overridepublic String toString() {return "Student{" +"name='" + name + '\'' +", age=" + age +'}';}@Overridepublic int compareTo(Student o) {return this.age-o.age;}
}
public class Test {public static void mysort(Comparable[] comparables){for (int i = 0; i < comparables.length-1; i++) {for(int j=0;j<comparables.length-1-i;j++){if(comparables[j].compareTo(comparables[j+1])>0){Comparable tmp=comparables[j];comparables[j]=comparables[j+1];comparables[j+1]=tmp;}}}}public static void main(String[] args) {Student[] students=new Student[]{new Student("zhansan",18),new Student("man",24),new Student("lebron",23)};mysort(students);System.out.println(Arrays.toString(students));}
}

3.总结
1.当前阶段如果我们想要进行自定义类型之间的比较,我们要使用Comparable接口。
2.重写接口里面的方法是我们根据需求来决定如何重写compareTo方法,重写后的compareTo方法里面的具体实现就是我们的比较规则。
2.Comparator接口
我们发现当我们使用Comparable接口时并不是那么灵活,因为它实现的比较规则是写死的,如果我们想要换一种比较规则,我们必须要对实现对比较方法里面的重新构造。
那有没有比较灵活的比较方式呢?答案就是Comparator接口。
AgeComparator类
public class AgeComparator implements Comparator<Student> {@Overridepublic int compare(Student o1, Student o2) {return o1.age- o2.age;}
}
NameComparator类
public class NameComparator implements Comparator<Student> {@Overridepublic int compare(Student o1, Student o2) {return o1.name.compareTo(o2.name);}
}
主函数部分
根据年龄排序
public class Test {public static void main(String[] args) {Student[] students=new Student[]{new Student("zhansan",18),new Student("man",24),new Student("lebron",23)};NameComparator nameComparator=new NameComparator();AgeComparator ageComparator=new AgeComparator();Arrays.sort(students,ageComparator);System.out.println(Arrays.toString(students));}
}

根据名字比较
public class Test {public static void main(String[] args) {Student[] students=new Student[]{new Student("zhansan",18),new Student("man",24),new Student("lebron",23)};NameComparator nameComparator=new NameComparator();AgeComparator ageComparator=new AgeComparator();Arrays.sort(students,nameComparator);System.out.println(Arrays.toString(students));}
}

这里我们定义了AgeComparator类和NameComparator类,它们都使用了Comparator这个接口,
然后在自己的类里面重写了compareTo方法。
根据以上类实现的对象可以认为是比较规则,将这些对象作为sort函数的参数,就可以灵活实现不同比较方式的转变。
相对于Comparable接口来说,Comparator不需要改变函数内部的具体实现来改变比较规则,只需改变函数的参数就行了,这样更安全也更方便。
相关文章:
Java-----Comparable接口和Comparator接口
在Java中,我们会经常使用到自定义类,那我们如何进行自定义类的比较呢? 1.Comparable接口 普通数据的比较 int a10;int b91;System.out.println(a<b); 那自定义类型可不可以这样比较呢?看一下代码 我们发现会报错,因为自定义…...
通信技术体会
比如 pcie可以看成是全连接的ahb bus,但又不是。 因为pcie还是axi(神似split/cutthrough)。(axi更多是接口而不是bus)。 pcie虽然物理层和usb都是serdes,但transaction layer就是上面这样的,也就…...
Linux系统安全及其应用
文章目录 一、用户账号安全管理1.1 系统账号的清理1.2 对用户账号的操作1.2.1 锁定和解锁用户1.2.2 删除无用账号 1.3 对重要文件进行锁定1.4 密码安全控制1.4.1 新建用户1.4.2 已有用户 二、历史命令管理2.1 历史命令限制2.2 自动清空历史命令 三、设置终端登录的安全管理3.1 …...
JVM内存划分类加载的过程双亲委派模型的详解
JVM内存划分 JVM也就是java进程,这个进程一旦跑起来就会从操作系统这里申请一大块内存空间,JVM接下来就要进一步的对这个大的空间进行划分,划分成不同区域,从而每个区域都有不同的功能作用,一共分为如下几个区域 1.堆…...
Java异常详解
Java异常详解 前言一、异常类的定义Java异常异常类的构成Java常见运行错误异常示例除以 0数组下标越界访问 null 对象 防御式编程异常的好处LBYL 风格的代码EAFP 风格的代码 二、异常的基本用法捕获异常基本语法代码示例不处理异常使用 try catch 后的程序执行过程catch 只能处…...
C++入门3——类与对象2(类的6个默认成员函数)
目录 1.类的6个默认成员函数 2. 构造函数 2.1 构造函数的概念 2.2 构造函数的特性 3. 析构函数 3.1 析构函数的概念 3.2 析构函数的特性 4.拷贝构造函数 4.1 拷贝构造函数的概念 4.2 拷贝构造函数的特性 5.赋值运算符重载函数 5.1运算符重载函数 5.2 赋值运算符重…...
CobaltStrike基本渗透
目录 CobaltStrike简介 主要功能: 使用注意: 在使用CobaltStrike进行渗透测试时,务必遵守法律法规,并获得合法授权。 CobaltStrike安装 前提 安装 服务端安装 windows安装 CS基本使用 监听器配置 一些基本的攻击…...
【linux深入剖析】进程间通信
🍁你好,我是 RO-BERRY 📗 致力于C、C、数据结构、TCP/IP、数据库等等一系列知识 🎄感谢你的陪伴与支持 ,故事既有了开头,就要画上一个完美的句号,让我们一起加油 目录 1.进程间通信目的2. 什么…...
关系数据库:关系模式
文章目录 基本概述关系的相关名词术语笛卡儿积与关系关系的类型 关系模式总结 基本概述 关系的相关名词术语 关系:简单来说,就是一张二维表格。属性(Attribute):也称字段或列,在现实世界中,要描述一个事务常常取若干…...
医学图像处理质量的评价方法
评判处理后医学图像的质量是确保图像处理技术有效性和可靠性的关键。以下是一些常用的图像质量评估方法和指标: 1. 主观评估 主观评估是由专业人员(如放射科医生)通过视觉检查对图像质量进行评分。常用的主观评估方法包括: 视觉…...
Ehcache Java 缓存框架
详解 下图是 Ehcache 在应用程序中的位置: Ecache 是一个广泛使用的 Java 缓存框架,能够有效提升应用性能,并减少与后端数据库的交互次数。它采用了一系列高级缓存策略,包括内存缓存、磁盘缓存、分布式缓存等,并提供了…...
详解Spring IoCDI(二)
目录 承接上文:详解Spring IoC&DI (一) 1.IoC详解 1.1方法注解Bean 1.2方法注解要配合类注解使用 1.3定义多个对象 1.4重命名Bean 1.5扫描路径 2.DI详解 2.1DI与IoC的关系 2.2属性注入 2.3构造方法注入 2.4Setter注入 2.5 三…...
说明白计算机网络之TCP的流量控制与拥塞控制之慢开始算法与拥塞避免算法
TCP的流量控制 利用滑动窗口实现流量控制 设A向B发送数据,连接建立时候,B告诉A自身的接收窗口大小,A的发送窗口大小不能超过接收方B的窗口大小 流量控制:发送方发送速率不要太快,要让接收方来得及接收。窗口大小的单…...
这款信创FTP软件,可实现安全稳定的文件传输
信创,即信息技术应用创新,2018年以来,受“华为、中兴事件”影响,国家将信创产业纳入国家战略,并提出了“28n”发展体系。“8”具体指金融、石油、电力、电信、交通、航空航天、医院、教育等主要行业。目前企业使用比较…...
代码随想录算法训练营第十天|232.用栈实现队列、225. 用队列实现栈
232.用栈实现队列 题目链接:232. 用栈实现队列 文档讲解:代码随想录 状态:写出来 ,但差强人意 思路: 定义两个容器,可以是Stack,也可以是Deque,stackIn相当于临时容器,用来存放元素&…...
STM32 IIC协议
本文代码使用 HAL 库。 文章目录 前言一、什么是IIC协议二、IIC信号三、IIC协议的通讯时序1. 写操作2. 读操作 四、上拉电阻作用总结 前言 从这篇文章开始为大家介绍一些通信协议,包括 UART,SPI,IIC等。 UART串口通讯协议 SPI通信协议 一、…...
Java生成随机数的几种方式
随机数,在一些特殊场景下,是非常常用的。比如一些测试和验证场景、安全加密、随机抽样等都有随机数的‘身影’。 一、 使用java.util.Random类 java.util.Random类提供了更全面的随机数生成功能,包括随机整数、随机浮点数、随机布尔值等。 p…...
【面试】什么是Java虚拟机
目录 1. 说明2. 关键点 1. 说明 1.Java虚拟机(Java Virtual Machine,简称JVM)是运行所有Java程序的抽象计算机,是Java语言的运行环境。2.JVM是Java平台无关性的关键,它允许Java程序在任何支持JVM的硬件和操作系统上运…...
Go 语言的基本构成、要素与编写规范
Go 语言,作为由 Google 开发的现代编程语言,以其简洁、高效和并发编程能力而著称。在构建高性能分布式系统和现代软件开发中,Go 语言正日益受到欢迎。本篇文章将详细探讨 Go 语言程序结构的各个要素,包括函数定义、注释规范、数据…...
从了解到掌握 Spark 计算框架(二)RDD
文章目录 RDD 概述RDD 组成RDD 的作用RDD 算子分类RDD 的创建1.从外部数据源读取2.从已有的集合或数组创建3.从已有的 RDD 进行转换 RDD 常用算子大全转换算子行动算子 RDD 算子综合练习RDD 依赖关系窄依赖宽依赖宽窄依赖算子区分 RDD 血统信息血统信息的作用血统信息的组成代码…...
【入坑系列】TiDB 强制索引在不同库下不生效问题
文章目录 背景SQL 优化情况线上SQL运行情况分析怀疑1:执行计划绑定问题?尝试:SHOW WARNINGS 查看警告探索 TiDB 的 USE_INDEX 写法Hint 不生效问题排查解决参考背景 项目中使用 TiDB 数据库,并对 SQL 进行优化了,添加了强制索引。 UAT 环境已经生效,但 PROD 环境强制索…...
【网络安全产品大调研系列】2. 体验漏洞扫描
前言 2023 年漏洞扫描服务市场规模预计为 3.06(十亿美元)。漏洞扫描服务市场行业预计将从 2024 年的 3.48(十亿美元)增长到 2032 年的 9.54(十亿美元)。预测期内漏洞扫描服务市场 CAGR(增长率&…...
土地利用/土地覆盖遥感解译与基于CLUE模型未来变化情景预测;从基础到高级,涵盖ArcGIS数据处理、ENVI遥感解译与CLUE模型情景模拟等
🔍 土地利用/土地覆盖数据是生态、环境和气象等诸多领域模型的关键输入参数。通过遥感影像解译技术,可以精准获取历史或当前任何一个区域的土地利用/土地覆盖情况。这些数据不仅能够用于评估区域生态环境的变化趋势,还能有效评价重大生态工程…...
ArcGIS Pro制作水平横向图例+多级标注
今天介绍下载ArcGIS Pro中如何设置水平横向图例。 之前我们介绍了ArcGIS的横向图例制作:ArcGIS横向、多列图例、顺序重排、符号居中、批量更改图例符号等等(ArcGIS出图图例8大技巧),那这次我们看看ArcGIS Pro如何更加快捷的操作。…...
优选算法第十二讲:队列 + 宽搜 优先级队列
优选算法第十二讲:队列 宽搜 && 优先级队列 1.N叉树的层序遍历2.二叉树的锯齿型层序遍历3.二叉树最大宽度4.在每个树行中找最大值5.优先级队列 -- 最后一块石头的重量6.数据流中的第K大元素7.前K个高频单词8.数据流的中位数 1.N叉树的层序遍历 2.二叉树的锯…...
laravel8+vue3.0+element-plus搭建方法
创建 laravel8 项目 composer create-project --prefer-dist laravel/laravel laravel8 8.* 安装 laravel/ui composer require laravel/ui 修改 package.json 文件 "devDependencies": {"vue/compiler-sfc": "^3.0.7","axios": …...
VM虚拟机网络配置(ubuntu24桥接模式):配置静态IP
编辑-虚拟网络编辑器-更改设置 选择桥接模式,然后找到相应的网卡(可以查看自己本机的网络连接) windows连接的网络点击查看属性 编辑虚拟机设置更改网络配置,选择刚才配置的桥接模式 静态ip设置: 我用的ubuntu24桌…...
【笔记】WSL 中 Rust 安装与测试完整记录
#工作记录 WSL 中 Rust 安装与测试完整记录 1. 运行环境 系统:Ubuntu 24.04 LTS (WSL2)架构:x86_64 (GNU/Linux)Rust 版本:rustc 1.87.0 (2025-05-09)Cargo 版本:cargo 1.87.0 (2025-05-06) 2. 安装 Rust 2.1 使用 Rust 官方安…...
【MATLAB代码】基于最大相关熵准则(MCC)的三维鲁棒卡尔曼滤波算法(MCC-KF),附源代码|订阅专栏后可直接查看
文章所述的代码实现了基于最大相关熵准则(MCC)的三维鲁棒卡尔曼滤波算法(MCC-KF),针对传感器观测数据中存在的脉冲型异常噪声问题,通过非线性加权机制提升滤波器的抗干扰能力。代码通过对比传统KF与MCC-KF在含异常值场景下的表现,验证了后者在状态估计鲁棒性方面的显著优…...
从面试角度回答Android中ContentProvider启动原理
Android中ContentProvider原理的面试角度解析,分为已启动和未启动两种场景: 一、ContentProvider已启动的情况 1. 核心流程 触发条件:当其他组件(如Activity、Service)通过ContentR…...
