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 血统信息血统信息的作用血统信息的组成代码…...
在软件开发中正确使用MySQL日期时间类型的深度解析
在日常软件开发场景中,时间信息的存储是底层且核心的需求。从金融交易的精确记账时间、用户操作的行为日志,到供应链系统的物流节点时间戳,时间数据的准确性直接决定业务逻辑的可靠性。MySQL作为主流关系型数据库,其日期时间类型的…...

高危文件识别的常用算法:原理、应用与企业场景
高危文件识别的常用算法:原理、应用与企业场景 高危文件识别旨在检测可能导致安全威胁的文件,如包含恶意代码、敏感数据或欺诈内容的文档,在企业协同办公环境中(如Teams、Google Workspace)尤为重要。结合大模型技术&…...
【服务器压力测试】本地PC电脑作为服务器运行时出现卡顿和资源紧张(Windows/Linux)
要让本地PC电脑作为服务器运行时出现卡顿和资源紧张的情况,可以通过以下几种方式模拟或触发: 1. 增加CPU负载 运行大量计算密集型任务,例如: 使用多线程循环执行复杂计算(如数学运算、加密解密等)。运行图…...

用docker来安装部署freeswitch记录
今天刚才测试一个callcenter的项目,所以尝试安装freeswitch 1、使用轩辕镜像 - 中国开发者首选的专业 Docker 镜像加速服务平台 编辑下面/etc/docker/daemon.json文件为 {"registry-mirrors": ["https://docker.xuanyuan.me"] }同时可以进入轩…...
[Java恶补day16] 238.除自身以外数组的乘积
给你一个整数数组 nums,返回 数组 answer ,其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积 。 题目数据 保证 数组 nums之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内。 请 不要使用除法,且在 O(n) 时间复杂度…...

3-11单元格区域边界定位(End属性)学习笔记
返回一个Range 对象,只读。该对象代表包含源区域的区域上端下端左端右端的最后一个单元格。等同于按键 End 向上键(End(xlUp))、End向下键(End(xlDown))、End向左键(End(xlToLeft)End向右键(End(xlToRight)) 注意:它移动的位置必须是相连的有内容的单元格…...

招商蛇口 | 执笔CID,启幕低密生活新境
作为中国城市生长的力量,招商蛇口以“美好生活承载者”为使命,深耕全球111座城市,以央企担当匠造时代理想人居。从深圳湾的开拓基因到西安高新CID的战略落子,招商蛇口始终与城市发展同频共振,以建筑诠释对土地与生活的…...

RSS 2025|从说明书学习复杂机器人操作任务:NUS邵林团队提出全新机器人装配技能学习框架Manual2Skill
视觉语言模型(Vision-Language Models, VLMs),为真实环境中的机器人操作任务提供了极具潜力的解决方案。 尽管 VLMs 取得了显著进展,机器人仍难以胜任复杂的长时程任务(如家具装配),主要受限于人…...

从“安全密码”到测试体系:Gitee Test 赋能关键领域软件质量保障
关键领域软件测试的"安全密码":Gitee Test如何破解行业痛点 在数字化浪潮席卷全球的今天,软件系统已成为国家关键领域的"神经中枢"。从国防军工到能源电力,从金融交易到交通管控,这些关乎国计民生的关键领域…...

通过 Ansible 在 Windows 2022 上安装 IIS Web 服务器
拓扑结构 这是一个用于通过 Ansible 部署 IIS Web 服务器的实验室拓扑。 前提条件: 在被管理的节点上安装WinRm 准备一张自签名的证书 开放防火墙入站tcp 5985 5986端口 准备自签名证书 PS C:\Users\azureuser> $cert New-SelfSignedCertificate -DnsName &…...