超详细的java Comparable,Comparator接口解析
前言
Hello大家好呀,在java中我们常常涉及到对象的比较,不同于基本数据类型,对于我们的自定义对象,需要我们自己去建立比较标准,例如我们自定义一个People类,这个类有name和age两个属性,那么问题来了,你如何比较两个人呢?很明显这个时候我们只有建立一个比较标准,只根据名字或者年龄比较,这个时候就需要Comparable和Comparator接口了,下面我将带领大家学习这两个接口
一,二者区别
首先呢,我想先为大家区别一下二者:Comparable与Comparator在逻辑上相似,都是根据比较对象的大小不同返回一个整型。但是类重写Comparable的compareTo方法只有一个,通常定义在要比较的类内部,由类的对象调用传入另一个该类的对象来比较,这当然有它的局限性,因为一个类中只能有一个compareTo方法,因此,只能指定一种比较标准,就像在刚才举例的Person类中重写comparable方法的话,只能指定按照名字或者年龄直接一种来排,但是在某些即需要我们根据名字排序,也需要我们根据年龄来排序的情境中就头疼了,因为compareTo方法没有重载,这个时候就需要Comparator接口,我们可以定义不同的按照不同标准比较两个对象的类来运用compare方法比较,现在听不懂也没关系,下面会为大家说明代码细节。
二,Comparable接口
以前面的Person类为例让类继承Comparable接口,同时按住Alt+Enter按键一直按到底,编译器会自动生成一段代码

这段代码没什么稀奇的,我们肯定是要重写它,但是我们需要注意它是传了一个Object的参数,(当然我们也可以自己修改成Person)这个参数需要我们强转成我们需要比较的对象才能够使用,那么我们先根据较简单的年龄比较,因为他是一个整形数据,如果调用该方法的对象年龄大于传入对象是返回一个大于0的数,他们年龄相等时返回0,否则返回一个小于0的数,于是我们得到了这样一段代码

当然,这段代码可不可以优化呢?显然,因为是整型数据的比较,可以写成下面的形式

ok那么我们就实现了用年龄比较两个Person对象的方法,后面内容我们会用这个方法实现一个排序算法这里先不测试这个方法继续往下讲,那么显然,对于String类型的name,不支持我们减号来比较两个对象的属性该怎么办呢?答案是,再调用一次ConpareTo方法

当然,这个时候调用的就是String内部的compareTo方法,我们不必关心代码实现细节,这也再次体现了封装的好处,我们不妨看看String是怎么实现这个方法的,按住ctrl鼠标点击这个方法便可以查看源码

当然我们这个时候,只要会用这个方法就行,代码放在下面,大家也能看出它的局限性,就是说下面我写根据姓名比较Person对象时必须把写过的根据年龄比较的代码注调
public class Test {public static void main(String[] args) {}
}
class Person implements Comparable {String name;int age;public Person(String name, int age) {this.name = name;this.age = age;}
// @Override
// public int compareTo(Object o) {
// Person tmp=(Person) o;//使用之前需强转
// return this.age-tmp.age;
// }@Overridepublic int compareTo(Object o) {Person tmp=(Person) o;//使用之前需强转return this.name.compareTo(tmp.name);}
}
三,Comparator接口
实现Comparator的compare方法与compareTo方法初始情况知识compare方法多了一个参数

我们已经说过最好新建一个比较类根据不同标准比较,与compareTo方法的区别是这里不能由对象调用,也就是不能存在this,然后代码实现细节和compareTo差别不大,大家可以看看下面这段代码思考一下Comparator接口怎么实现根据不同标准比较的
import java.util.Comparator;
public class Test {public static void main(String[] args) {}
}
class Person {String name;int age;public Person(String name, int age) {this.name = name;this.age = age;}
}
class AgeCompare implements Comparator<Person>{//这里<Person>是声明这个接口用于比较Person类,这部分知识后面还会讲@Overridepublic int compare(Person person, Person t1) {return person.age-t1.age;}
}
class NameCompare implements Comparator<Person>{@Overridepublic int compare(Person person, Person t1) {return person.name.compareTo(t1.name);}
}
我们再比较时只需实例化一个比较类在调用方法传入两给person对象就好啦
四,冒泡排序实现排序person对象
代码实现细节都放在注释里啦,先上代码
import java.util.Comparator;public class Test {public static void main(String[] args) {Person person1=new Person("a",15);Person person2=new Person("b",12);Person person3=new Person("c",17);Person person4=new Person("d",13);Person person5=new Person("e",19);//实例化五个对象Person[] people={person1,person5,person3,person2,person4};//乱序Sort.sort(people);//这个时候就排好了System.out.println(people[0]);System.out.println(people[1]);System.out.println(people[2]);System.out.println(people[3]);System.out.println(people[4]);}
}
class Person implements Comparable{String name;int age;public Person(String name, int age) {this.name = name;this.age = age;}@Overridepublic String toString() {return "Person{" +"name='" + name + '\'' +", age=" + age +'}';}@Overridepublic int compareTo(Object o) {return this.age-((Person)o).age;}
}class Sort {public static void sort(Comparable[] comparable) {//注意这里用接口数组表示实现了这个接口也就是这个数组一定是可比较的for (int i = 0; i < comparable.length - 1; i++) {for (int j = 0; j < comparable.length - 1; j++) {//标准冒泡排序if (comparable[j].compareTo(comparable[j + 1]) > 0) {//因为比较的是任意类型数据,这里一定是调用我们重写的compareTo方法Comparable tmp=comparable[j];comparable[j]=comparable[j+1];comparable[j+1]=tmp;}}}}
}

注意我们如果要修改排序顺序选择修改compareTo方法,修改一行代码即可

改为


同样,要根据名字排序也只需动compareTo方法


这样我们的排序就完成啦
本期博客就到这里,感谢大家阅读,我们下期见
相关文章:
超详细的java Comparable,Comparator接口解析
前言 Hello大家好呀,在java中我们常常涉及到对象的比较,不同于基本数据类型,对于我们的自定义对象,需要我们自己去建立比较标准,例如我们自定义一个People类,这个类有name和age两个属性,那么问…...
Java使用GDAL来解析KMZ及KML实战
目录 前言 一、在GQIS中浏览数据 1、关于空间参考 2、属性表格 二、GDAL的相关驱动及解析实战 1、GDAL中的KMZ驱动 2、GDAL实际解析 三、数据解析成果 1、KML解析结果 2、KMZ文件入库 四、总结 前言 在前面的博客中讲过纯Java实现Google地图的KMZ和KML文件的解析&…...
【vuex小试牛刀】
了解vuex核心概念请移步 https://vuex.vuejs.org/zh/ # 一、初始vuex # 1.1 vuex是什么 就是把需要共享的变量全部存储在一个对象里面,然后将这个对象放在顶层组件中供其他组件使用 父子组件通信时,我们通常会采用 props emit 这种方式。但当通信双方不…...
React - 实现走马灯组件
一、实现效果 二、源码分析 import {useRef, useState} from "react";export const Carousel () > {const images [{id: 3, url: https://sslstage3.sephorastatic.cn/products/2/4/6/8/1/6/1_n_new03504_100x100.jpg}, {id: 1, url: https://sslstage2.sephor…...
【学习笔记】Windows GDI绘图(十三)动画播放ImageAnimator(可调速)
文章目录 前言定义方法CanAnimate 是否可动画显示Animate 动画显示多帧图像UpdateFramesStopAnimate终止动画Image.GetFrameCount 获取动画总帧数Image.GetPropertyItem(0x5100) 获取帧延迟 自定义GIF播放(可调速) 前言 在前一篇文章中用到ImageAnimator获取了GIF动画的一些属…...
fps游戏如何快速定位矩阵
fps游戏如何快速定位矩阵 矩阵特点: 1、第一行第一列值的范围在**-1 ---- 1**之间,如果开镜之后值会变大。 2、第一行第三列的值始终为 0。 3、第一行第四列 的值比较大 , >300或者**<-300**。 根据这三个特点,定位矩阵已经足够了…...
【机器学习基础】Python编程06:五个实用练习题的解析与总结
Python是一种广泛使用的高级编程语言,它在机器学习领域中的重要性主要体现在以下几个方面: 简洁易学:Python语法简洁清晰,易于学习,使得初学者能够快速上手机器学习项目。 丰富的库支持:Python拥有大量的机器学习库,如scikit-learn、TensorFlow、Keras和PyTorch等,这些…...
R可视化:生存分析森林图
在R语言中,使用forestplot包来绘制生存分析的森林图是一个专业且直观的方式来展示各种风险因素或治疗对生存结果的影响。森林图(Forest Plot)常用于展示多项研究的效应量和其可信区间,尤其在生存分析中,它可以清晰地显示不同变量或因素对生存时间的影响程度和统计显著性。…...
一个 python+tensorFlow训练1万张图片分类的简单直观例子( 回答由百度 AI 给出 )
问题:给定一个文件夹 train_images,里面有10000张30*30像素的灰度值图片,第1~第10000张图片的名称分别为 00001.png、 00002.png、... 09999.png、10000.png,train_images 下面还有一个 image_category_map.txt文件, 文件的内容…...
DBeaver无法连接Clickhouse,连接失败
DBeaver默认下载的是0.2.6版本的驱动,但是一直连接失败: 报错提示 解决办法 点击上图中的Open Driver Configuration点击库 - 重置为默认状态在弹出的窗口中修改驱动版本号为0.2.4或者其他版本(我没有试用过其他版本)࿰…...
python基础实例
下一个更大的数 定义一个Solution类,用于实现next_great方法 class Solution: def next_great(self, nums1, nums2): # 初始化一个空字典answer,用于存储答案 answer {} # 初始化一个空列表stack,用于存储待比较的数字 stack [] # 遍历nu…...
ADASIS V2 协议-1
ADAS V2协议-1 1 简介2 版本控制3 ADASIS v23.1 ADASIS v2 Horizon (地平线)3.2 ADASIS v2的构建3.3 ADASIS v2 Horizon Provider (ADAS V2地平线提供者)3.4 paths and offsets (路径和偏移量)3.5 Path Pro…...
人工智能安全风险分析及应对策略
文│中国移动通信集团有限公司信息安全管理与运行中心 张峰 江为强 邱勤 郭中元 王光涛 人工智能(AI)是引领新一轮科技革命和产业变革的关键技术。人工智能赋能网络安全的同时,也会带来前所未有的安全风险。本文在介绍人工智能技术赋能网络安…...
Python驱动下的AI革命:技术赋能与案例解析
在当今这个信息化、数据化的时代,人工智能(AI)已经成为推动社会发展的重要力量。而Python,作为一种简单易学、功能强大的编程语言,在AI领域的应用中发挥着至关重要的作用。本文将探讨Python在AI领域的应用、其背后的技…...
JavaScrip轮播图
前言 在网页设计中,轮播图(Carousel)已经成为一种常见的元素,用于展示一系列的图片或内容卡片。它们不仅能够吸引用户的注意力,还能节省空间,使得用户可以在有限的空间内获得更多的信息。今天,我…...
达梦8 网络中断对系统的影响
测试环境:三节点实时主从 版本:--03134283938-20221019-172201-20018 测试1 系统没有启动确认监视器 关闭节点3网卡 登录节点1检查主库状态 显示向节点2发送归档成功,但无法收到节点3的消息,节点1挂起 日志报错如下…...
OpenAI发布GPT-4思维破解新策略,Ilya亦有贡献!
OpenAI正在研究如何破解GPT-4的思维,并公开了超级对齐团队的工作,Ilya Sutskever也在作者名单中。 论文地址:https://cdn.openai.com/papers/sparse-autoencoders.pdf 代码:https://github.com/openai/sparse_autoencoder 特征可…...
[消息队列 Kafka] Kafka 架构组件及其特性(二)Producer原理
这边整理下Kafka三大主要组件Producer原理。 目录 一、Producer发送消息源码流程 二、ACK应答机制和ISR机制 1)ACK应答机制 2)ISR机制 三、消息的幂等性 四、Kafka生产者事务 一、Producer发送消息源码流程 Producer发送消息流程如上图。主要是用…...
faiss ivfpq索引构建
假设已有训练好的向量值,构建索引(nlist和随机样本按需选取) import numpy as np import faiss import pickle from tqdm import tqdm import time import os import random# 读取嵌入向量并保留对应关系 def read_embeddings(directory, ba…...
ffmpeg视频编码原理和实战-(2)视频帧的创建和编码packet压缩
源文件: #include <iostream> using namespace std; extern "C" { //指定函数是c语言函数,函数名不包含重载标注 //引用ffmpeg头文件 #include <libavcodec/avcodec.h> } //预处理指令导入库 #pragma comment(lib,"avcodec.…...
日语AI面试高效通关秘籍:专业解读与青柚面试智能助攻
在如今就业市场竞争日益激烈的背景下,越来越多的求职者将目光投向了日本及中日双语岗位。但是,一场日语面试往往让许多人感到步履维艰。你是否也曾因为面试官抛出的“刁钻问题”而心生畏惧?面对生疏的日语交流环境,即便提前恶补了…...
ssc377d修改flash分区大小
1、flash的分区默认分配16M、 / # df -h Filesystem Size Used Available Use% Mounted on /dev/root 1.9M 1.9M 0 100% / /dev/mtdblock4 3.0M...
GitHub 趋势日报 (2025年06月08日)
📊 由 TrendForge 系统生成 | 🌐 https://trendforge.devlive.org/ 🌐 本日报中的项目描述已自动翻译为中文 📈 今日获星趋势图 今日获星趋势图 884 cognee 566 dify 414 HumanSystemOptimization 414 omni-tools 321 note-gen …...
算法笔记2
1.字符串拼接最好用StringBuilder,不用String 2.创建List<>类型的数组并创建内存 List arr[] new ArrayList[26]; Arrays.setAll(arr, i -> new ArrayList<>()); 3.去掉首尾空格...
管理学院权限管理系统开发总结
文章目录 🎓 管理学院权限管理系统开发总结 - 现代化Web应用实践之路📝 项目概述🏗️ 技术架构设计后端技术栈前端技术栈 💡 核心功能特性1. 用户管理模块2. 权限管理系统3. 统计报表功能4. 用户体验优化 🗄️ 数据库设…...
Netty从入门到进阶(二)
二、Netty入门 1. 概述 1.1 Netty是什么 Netty is an asynchronous event-driven network application framework for rapid development of maintainable high performance protocol servers & clients. Netty是一个异步的、基于事件驱动的网络应用框架,用于…...
iview框架主题色的应用
1.下载 less要使用3.0.0以下的版本 npm install less2.7.3 npm install less-loader4.0.52./src/config/theme.js文件 module.exports {yellow: {theme-color: #FDCE04},blue: {theme-color: #547CE7} }在sass中使用theme配置的颜色主题,无需引入,直接可…...
苹果AI眼镜:从“工具”到“社交姿态”的范式革命——重新定义AI交互入口的未来机会
在2025年的AI硬件浪潮中,苹果AI眼镜(Apple Glasses)正在引发一场关于“人机交互形态”的深度思考。它并非简单地替代AirPods或Apple Watch,而是开辟了一个全新的、日常可接受的AI入口。其核心价值不在于功能的堆叠,而在于如何通过形态设计打破社交壁垒,成为用户“全天佩戴…...
Chrome 浏览器前端与客户端双向通信实战
Chrome 前端(即页面 JS / Web UI)与客户端(C 后端)的交互机制,是 Chromium 架构中非常核心的一环。下面我将按常见场景,从通道、流程、技术栈几个角度做一套完整的分析,特别适合你这种在分析和改…...
git: early EOF
macOS报错: Initialized empty Git repository in /usr/local/Homebrew/Library/Taps/homebrew/homebrew-core/.git/ remote: Enumerating objects: 2691797, done. remote: Counting objects: 100% (1760/1760), done. remote: Compressing objects: 100% (636/636…...
