超详细的java Comparable,Comparator接口解析

news2024/11/18 1:38:45

前言

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;
//    }
    @Override
    public 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类,这部分知识后面还会讲
    @Override
    public int compare(Person person, Person t1) {
        return person.age-t1.age;
    }
}
class NameCompare implements Comparator<Person>{
    @Override
    public 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;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
    @Override
    public 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方法

这样我们的排序就完成啦

本期博客就到这里,感谢大家阅读,我们下期见

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1799726.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

QT creator c动态链接库的创建与调用

QT creator c动态链接库的创建与调用 QT5.15.2 1.创建dll项目 确保两类型选择正确 2.选择MinGW 64-bit 3.点击完成 pro文件参考&#xff1a; QT - guiTEMPLATE lib DEFINES QT_DLL_DEMO_LIBRARYCONFIG c17# You can make your code fail to compile if it uses deprecat…

计算机组成结构—IO系统概述

目录 一、I/O 系统的发展 1. 早期阶段 2. 接口模块和 DMA 阶段 3. 通道结构阶段 4. 处理机阶段 二、I/O 系统的组成 1. I/O 软件 2. I/O 硬件 三、I/O 设备 1. I/O 设备分类 2. I/O 设备的组成 在计算机中&#xff0c;除 CPU 和主存两大模块之外&#xff0c;第三个重…

Vue项目安装axios报错npm error code ERESOLVE npm error ERESOLVE could not resolve解决方法

在Vue项目中安装axios时报错 解决方法&#xff1a;在npm命令后面加--legacy-peer-deps 例如&#xff1a;npm install axios --save --legacy-peer-deps 因为别的需求我把node版本重装到了最新版&#xff08;不知道是不是这个原因&#xff09;&#xff0c;后来在项目中安装axi…

STM32作业实现(四)光敏传感器

目录 STM32作业设计 STM32作业实现(一)串口通信 STM32作业实现(二)串口控制led STM32作业实现(三)串口控制有源蜂鸣器 STM32作业实现(四)光敏传感器 STM32作业实现(五)温湿度传感器dht11 STM32作业实现(六)闪存保存数据 STM32作业实现(七)OLED显示数据 STM32作业实现(八)触摸按…

【Python爬虫单点登录实战】PyExecJS破解慧职教:过河源技术学院单点登录统一身份认证

目录 前言大致分析PyExecJS 使用案例pip 安装:Demo:输出:案例1.访问目标网站的登录页面并查看源码2.将js放到和py脚本同一级目录下3. 编写Python脚本来调用js破解单点登录实战提取密钥参数清洗数据登陆测试单点登录获取ticket获取jsessionid获取token成功我的专栏前言 博主提供…

Python 知识图谱补全,Knowledge Graph Completion,基于大模型的知识图谱补全,基于LLMs的KGC任务

今天讲一篇文章《Exploring Large Language Models for Knowledge Graph Completion》 &#xff0c;这篇文章主题&#xff1a;基于大模型做知识图谱补全 1.文章主要思想&#xff1a; 本章描述知识图谱补全中的三个任务&#xff1a;三元组分类、关系预测和实体(链接)预测&…

微信如何防止被对方拉黑删除?一招教你解决!文末附软件!

你一定不知道&#xff0c;微信可以防止被对方拉黑删除&#xff0c;秒变无敌。只需一招就能解决&#xff01;赶快来学&#xff01;文末有惊喜&#xff01; 惹到某些重要人物&#xff08;比如女朋友&#xff09;&#xff0c;被删除拉黑一条龙&#xff0c;那真的是太令人沮丧了&a…

Ubuntu server 24 (Linux) AdGuard Home +SmartDNS 安装配置 搭建去广告快速DNS

一 SmartDNS 安装 &#xff0c;可参考&#xff1a;Ubuntu server 24 (Linux) 安装部署smartdns 搭建智能DNS服务器-CSDN博客 二 安装AdGuard 1 下载地址&#xff1a;GitHub - AdguardTeam/AdGuardHome: Network-wide ads & trackers blocking DNS server 2 解压安装 #下…

路由器重启真的好吗?多久重启一次更好?

前言 小白前段时间发现自己家的OpenWRT软路由上网特别慢&#xff0c;有时候通话还有点卡顿。 然而有个朋友用的普通路由器也有类似的问题&#xff0c;而且有时候根本上不去网。 解决的办法很简单&#xff1a;重启路由器。 重启路由器&#xff1f; 但路由器重启是真的好吗&a…

链表反转--理解链表指针的基本操作

链表反转--理解链表指针的基本操作 链表反转的方法--主要是理解链表指针链表心得类节点是对象和指针区别&#xff1a; 链表反转的方法–主要是理解链表指针 根据值创建新列表 用一个链表指针代替整个新链表 两个链表的赋值 递归求解反向链表 用一个链表代替前后链表数…

将div渲染成textarea框,类似于ant design 的TextArea

一 先看效果 原始效果 输入时效果 二 代码如下 1. html 代码 <div className{style.divTextArea} contentEditable"true"></div> 2. Css(Less)代码 .divTextArea {width: 90%;margin-top: 10px;line-height: 28px;min-height: 60px;border: 1px solid …

优雅谈大模型10:MoE

大模型技术论文不断&#xff0c;每个月总会新增上千篇。本专栏精选论文重点解读&#xff0c;主题还是围绕着行业实践和工程量产。若在某个环节出现卡点&#xff0c;可以回到大模型必备腔调或者LLM背后的基础模型新阅读。而最新科技&#xff08;Mamba,xLSTM,KAN&#xff09;则提…

牛客java基础(一)

A 解析 : java源程序只允许一个public类存在 &#xff0c;且与文件名同名 ; D hashCode方法本质就是一个哈希函数&#xff0c;这是Object类的作者说明的。Object类的作者在注释的最后一段的括号中写道&#xff1a;将对象的地址值映射为integer类型的哈希值。但hashCode()并不…

使用python绘制桑基图

使用python绘制桑基图 桑基图效果代码 桑基图 桑基图&#xff08;Sankey Diagram&#xff09;是一种用来表示流动&#xff08;如能源、资金、材料等&#xff09;在不同实体之间转移的图表。 每个流的宽度与流量成正比&#xff0c;通常用于显示能量或成本流动的分布情况。 桑基…

【TB作品】MSP430F149单片机,广告牌,滚动显示

LCD1602滚动显示切换播放暂停字符串 显示Public Places 显示No Smoking 播放 暂停 部分代码 char zifu1[] "Public Places "; char zifu2[] "Class Now "; char zifu3[] "No admittance "; char *zifu[] { zifu1, zifu2, zifu3 }…

初识C++ · 模板进阶

目录 前言&#xff1a; 1 非类型模板参数 2 按需实例化 3 模板特化 4 模板的分离编译 前言&#xff1a; 前面模板我们会了简单的使用&#xff0c;这里带来模板的进阶&#xff0c;当然&#xff0c;也就那么几个知识点&#xff0c;并不太难。 1 非类型模板参数 先来看这样…

C语言过度C++语法补充(面向对象之前语法)

目录 1. C相较于C语言新增的语法 0. C 中的输入输出 1. 命名空间 1. 我们如何定义一个命名空间&#xff1f; 2. 如何使用一个命名空间 3. 命名空间中可以定义什么&#xff1f; 4. 在 相同或者不同 的文件中如果出现 同名的命名空间 会如何&#xff1f; 5. 总结~~撒花~~…

大模型基础——从零实现一个Transformer(1)

一、Transformer模型架构图 主要模块&#xff1a; embedding层&#xff1a; Input/Output Embedding&#xff1a; 将每个标记(token)转换为对应的向量表示。 Positional Encoding&#xff1a;由于没有时序信息&#xff0c;需要额外加入位置编码。 N个 block堆叠: Multi-Head …

vue不同页面切换的方式(Vue动态组件)

v-if实现 <!--Calender.vue--> <template><a-calendar v-model:value"value" panelChange"onPanelChange" /></template> <script setup> import { ref } from vue; const value ref(); const onPanelChange (value, mod…

Oracle EBS AP发票验证-计税期间出现意外错误解决方法

系统版本 RDBMS : 12.1.0.2.0 Oracle Applications : 12.2.6 问题症状: **打开发票题头或发票行“税详细信息”**错误提示如下: 由于以下原因而无法针对"税"窗口中所做的修改更新 Oraclee Payables信息: 尚未为税率或帐户来源税率设置可退回税/应纳税额帐户。请…