Java对象的比较

目录

PriorityQueue中插入对象

元素的比较

基本类型的比较

对象比较问题

 对象的比较

覆写基类的equals

基于Comparble接口类的比较

基于比较器的比较

三种方式的对比

集合框架中PriorityQueue的比较方式


PriorityQueue中插入对象

上一篇博文中我们讲了优先级队列,优先级队列插入元素时有个要求:插入的元素不能是null或者元素之间必须能够进行比较,为了简单起见,我们只是插入了Integer类型,那优先级队列中能否插入自定义类型对象呢?

来看下面这个例子:

class Student {public int age;//年龄public String name;//姓名public Student(int age, String name) {this.age = age;this.name = name;}
}public class TestPriorityQueue {public static void TestPriorityQueue(){PriorityQueue<Student> p = new PriorityQueue<>();p.offer(new Student(18, "lisi"));p.offer(new Student(6, "wangwu"));}public static void main(String[] args) {TestPriorityQueue();}
}

你会发现这样的运行结果:

出现这种情况是因为优先队列底层使用堆,而向堆中插入元素时,为了满足堆的性质,必须要进行元素的比较,而此时Student是没有办法直接进行比较的,因此抛出异常。 

元素的比较

基本类型的比较

在Java中,基本类型的对象可以直接比较大小。

public class TestCompare {public static void main(String[] args) {int a = 10;int b = 20;System.out.println(a > b);System.out.println(a < b);System.out.println(a == b);char c1 = 'A';char c2 = 'B';System.out.println(c1 > c2);System.out.println(c1 < c2);System.out.println(c1 == c2);boolean b1 = true;boolean b2 = false;System.out.println(b1 == b2);System.out.println(b1 != b2);}
}

对象比较问题

class Student {public int age;//年龄public String name;//姓名public Student(int age, String name) {this.age = age;this.name = name;}
}public class TestPriorityQueue {public static void main(String[] args) {Student s1 = new Student(18, "lisi");Student s2 = new Student(6, "wangwu");Student s3 = s1;//System.out.println(s1 > s2); 编译报错System.out.println(s1 == s2);//编译成功->打印false,因为它们指向的是不同对象//System.out.println(s1 < s2); 编译报错System.out.println(s1 == s2);//编译成功->打印true,因为s1和s3指向的是同一对象}
}

 从编译结果可以看出,Java中引用类型的变量不能直接按照>或者<方式进行比较。那为什么==可以比较?

那是因为:对于用户实现自定义类型,都默认继承自Object类,而Object类中提供了equal方法,而==默认情况下调用的就是equal方法,但是该方法的比较规则是:没有比较引用变量引用对象的内容,而是直接比较引用变量的地址,但有些情况下该种比较就不符合题意。

//Object中equal的实现,可以看到:直接比较的是两个引用变量的地址
public boolean equals(Object obj) {return (this == obj);
}

 对象的比较

有些情况下,需要比较的是对象的内容,比如:向优先级队列中插入某个对象时,需要对按照对象中的内容来调整堆,那该如何处理呢?有以下几种方法:

覆写基类的equals

代码如下:

class Student {public int age;//年龄public String name;//姓名public Student(int age, String name) {this.age = age;this.name = name;}}@Overridepublic boolean equals(Object o) {//自己和自己比较if(this == o) {return true;//指向一个对象则返回true}//o如果是null对象,或者o不是Student的子类if(o == null || !(o instanceof Student)) {return false;}//注意基本类型可以直接比较,但引用类型最好调用其equal方法Student c = (Student)o;return age == c.age && name.equals(c.name);}

注意:一般覆写equals的套路如上

1.如果指向同一个对象,返回true

2.如果传入的是null,返回false

3.如果传入的对象类型不是Student, 返回false

4.按照类的实现目标完成比较,例如这里只要年龄和姓名一样,就认为是相同的学生

5.注意下调调用其它的引用类型的比较也需要equals,例如这里的name比较

覆写基类equals的方式虽然可以比较,但缺陷是:equal只能按照相等进行比较,不能按照大于,小于的方式进行比较。

基于Comparble接口类的比较

Comparble是JDK提供的泛型比较接口类,源码实现具体如下:

public interface Comparable<E> {//返回值//<0:表示this指向的对象小于o指向的对象//==0:表示this指向的对象等于o指向的对象//>0:表示this指向的对象大于o指向的对象int compareTo(E o);
}

对用用户自定义类型,如果想要按照大小与方式进行比较时:在定义类时,实现Comparble接口即可,然后在类中重写compareTo方法 

使用举例:

public class Student implements Comparable<Student> {public int age;public String name;public Student(int age, String name) {this.age = age;this.name = name;}//根据年龄比较,不管姓名//这里我们认为null是最小的@Overridepublic int compareTo(Student o) {if(o == null) {return 1;}return age - o.age;}public static void main(String[] args) {Student s1 = new Student(18, "lisi");Student s2 = new Student(6, "wangwu");Student s3 = new Student(18, "wangwu");System.out.println(s1.compareTo(s3));//==0System.out.println(s1.compareTo(s2));//>0System.out.println(s2.compareTo(s1));//<0}
}

Comparable是java.lang中的接口类,可以直接使用。

基于比较器的比较

按照比较器方式进行比较,具体步骤如下:

用户自定义比较器类,实现Comparator接口 

​
public interface Comparator<T> {//返回值//<0:表示o1指向的对象小于o2指向的对象//==0:表示o1指向的对象等于o2指向的对象//>0:表示o1指向的对象大于o2指向的对象int compare(T o1, T o2);
}​

注意:区分Comparable和Comparator. 

覆写Comparator中的compare方法

代码如下:

class Student {public int age;//年龄public String name;//姓名public Student(int age, String name) {this.age = age;this.name = name;}
}public class StudentComparator implements Comparator<Student> {//根据年龄比较,不管姓名//这里我们认为null是最小的@Overridepublic int compare(Student o1, Student o2) {if(o1 == o2) {return 0;}if(o1 == null) {return -1;}if(o2 == null) {return 1;}return o1.age - o2.age;}public static void main(String[] args) {Student p = new Student(18, "lisi");Student q = new Student(6, "wangwu");Student o = new Student(18, "wangwu");//定义比较器对象StudentComparator comparator = new StudentComparator();//使用比较器对象进行比较System.out.println(comparator.compare(p, o));System.out.println(comparator.compare(p, q));System.out.println(comparator.compare(q, p));}
}

注意:Comparator是java.util包中的泛型接口类,使用时必须导入对应的包 

三种方式的对比

覆写的方法说明
Object.equals因为所有类都是继承自Object的,所以直接覆写即可,不过只能比较相等与否
Comparable.compareTo需要手动实现接口,侵入性比较强,但一旦实现,每次用该类都有顺序,属于内部顺序
Comparator.compare需要实现一个比较器对象,对待比较类的侵入性弱,但对算法代码实现侵入性强

集合框架中PriorityQueue的比较方式

集合框架中的PriorityQueue底层使用堆结构,因此其内部的元素必须要能够比较大小,Priority采用了:Comparble和Comparator两种方式。

1.Comparable是默认的内部比较方式,如果用户插入自定义类型对象时,该类对象必须要实现Comparable接口,并覆写compareTo方法。

2.用户也可以选择使用比较器对象,如果用户插入自定义类型对象时,必须要提供一个比较器类,让该类实现Comparator接口并覆写compare方法。

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

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

相关文章

golang 拉取 bitbucket.org 私有库

以 bitbucket.org 平台和mac电脑为例 前置条件私库需要给你账号权限&#xff0c;可拉取的权限&#xff0c;否则无法进行正常拉取 我们采用ssh方式&#xff0c;需要在本地生成对应的 rsa 的公钥和私钥&#xff0c;将公钥配置如下图&#xff1a; 在 .ssh/config 写入你的配置 H…

2015架构案例(五十一)

第5题 【说明】某信息技术公司计划开发一套在线投票系统&#xff0c;用于为市场调研、信息调查和销售反馈等业务提供服务。该系统计划通过大量宣传和奖品鼓励的方式快速积累用户&#xff0c;当用户规模扩大到一定程度时&#xff0c;开始联系相关企业提供信息服务&#xff0c;并…

Codeforces Round 903 (Div. 3) C(矩形旋转之后对应的坐标)

题目链接&#xff1a;Codeforces Round 903 (Div. 3) C 题目&#xff1a; 思想&#xff1a; 旋转之后对应的坐标&#xff1a; &#xff08;i&#xff0c;j&#xff09;&#xff08;n1-j&#xff0c;i&#xff09;&#xff08;n1-i&#xff0c;n1-j&#xff09;&#xff08;j…

浅谈MDK, IAR,CLANG和GCC的局部变量字节对齐处理差异(2023-10-13)

视频&#xff1a; https://www.bilibili.com/video/BV1CB4y1Z7kA 浅谈MDK, IAR, CLANG和GCC的局部变量字节对齐处理差异 问题由来&#xff1a; 早期这个帖子里面的局部变量对齐仅测试了MDK AC5&#xff0c;但项目中使用AC6发现了新问题&#xff0c;看来AAPCS规约研究的还是不…

ArcGIS笔记4_水动力模型验证不理想时如何修改局部水深地形

本文目录 前言Step 1 模型验证不理想的情况Step 2 修改确值点并重新插值 前言 本章主要服务于MIKE水动力模型的调整修改工作。水动力模型跑完之后&#xff0c;常常会出现验证结果不理想的情况&#xff0c;比如潮位验证中&#xff0c;实测站点数据与模拟数据相差很大&#xff0…

苹果ios用户下载ipa文件内测签名的后的app应用下载安装到手机图标消失了-解决方案

下载好的应用竟然找不到了&#xff1f;这么神奇&#xff1f;我尝试了解了一下复原了同学给我的内容果然出现了我尝试科技了一下&#xff0c;总结了以下的可能性&#xff01;同学如果这个回答解决了你的困扰&#xff0c;同学给个赞&#xff0c;如果你有更好的排查方案评论区分享…

Modelsim查看波形窗口内断言(SVA)消息指示器

步骤1&#xff1a;创建工程并编译完成 在相应目录下创建好工程并编译无错误后&#xff1b; 步骤二&#xff1a; 在菜单栏中选择“Simulate”—>“Start Simulation”—>“Others”,在“Others Vsim Options”中输入 -msgmode both -displaymsgmode both 步骤三&#xf…

UI自动化测试 —— Jenkins配置

前一段时间帮助团队搭建了UI自动化环境&#xff0c;这里将Jenkins环境的一些配置分享给大家。 背景&#xff1a; 团队下半年的目标之一是实现自动化测试&#xff0c;这里要吐槽一下&#xff0c;之前开发的测试平台了&#xff0c;最初的目的是用来做接口自动化测试和性能测试&…

SQL Server远程登录失败

SQL Server远程登录失败 检查SQL SERVER 是否允许远程访问. 具体步骤: 1)在远端SQL Server主机上,打开SSMS并连接数据库 2)在相应”数据库”上单击右键,选择”属性” 3)选择”连接”选项卡,检查”远程服务器连接”下,RPC服务是否选择. 设置SQL Server相关TCP连接 1.打开SQL Se…

下载Python的不同版本在同一台电脑上如何共存

1. 下载安装不同版本的Python 官网下载&#xff1a;https://www.python.org/downloads/安装自己需要的版本&#xff08;我这里以Python3.6和Python3.9为例&#xff0c;下载安装细节不过多赘述&#xff09; &#xff08;这里的安装路径自己设定&#xff0c;命名最好是根据下载…

项目管理之六大目标及成功方程式

项目管理的六大目标分别是范围、质量、时间、成本、收益和风险。在项目开始之前&#xff0c;需要明确了解项目的范围&#xff0c;并在项目执行过程中对范围进行严格控制&#xff0c;确保项目不偏离既定的范围。同时&#xff0c;需要明确项目的质量标准和预期成果&#xff0c;然…

使用 Apache Kafka 进行发布-订阅通信中的微服务

发布-订阅消息系统在任何企业架构中都发挥着重要作用&#xff0c;因为它可以实现可靠的集成&#xff0c;而无需紧密耦合应用程序。在解耦的系统之间共享数据的能力并不是一个容易解决的问题。 考虑一家拥有多个使用不同语言和平台独立构建的应用程序的企业。它需要响应地共享数…

frp隧道(流量代理)

代理 代理使用场景 拿下远程web服务器webshell连接不稳定&#xff0c;需要使用稳定的木马程序远程服务器无法直接连接攻击者电脑&#xff08;内网IP&#xff09;需要借助公网vps转发来自失陷服务器的木马流量借助frp服务器&#xff08;vps&#xff09;和客户端&#xff08;内…

MOS管经常被烧坏,多半是这些原因

MOS管&#xff0c;即金属氧化物半导体场效应管&#xff0c;是电子电路中常见的重要元件&#xff0c;因此很多电子工程师会选择在电路板上使用MOS管&#xff0c;但在使用过程中经常会遇见MOS管莫名被烧毁的问题&#xff0c;这些问题是如何造成的&#xff1f;如何解决&#xff1f…

彻底解决Qt中文乱码以及汉字编码的问题(UTF-8/GBK)

彻底解决Qt中文乱码以及汉字编码的问题&#xff08;UTF-8/GBK&#xff09; Chapter1 (彻底解决Qt中文乱码以及汉字编码的问题&#xff08;UTF-8/GBK&#xff09;一、Qt Creator环境设置二、编码知识科普Qt常见的两种编码是:UTF-8和GBK 三、编码转换四、QString显示中文乱码的原…

香港服务器在大陆连不上怎么回事?

众所周知&#xff0c;香港服务器与中国内地的网络连通性是比较好的&#xff0c;不仅是机房地理距离的加持&#xff0c;还有就是利用CN2 GIABGP高速线路&#xff0c;参考恒创科技香港服务器访问内地网站&#xff0c;无需绕国际线路转换再到大陆&#xff0c;访问速度会比较快。但…

【交叉编译】tslib库交叉编译

tslib 是一个捕捉触屏事件的工具。qt 库在交叉编译的时候&#xff0c;提供了 -tslib 选项&#xff0c;使用该选项需要提前对 tslib 库进行交叉编译。 目录 1、源码下载 2、安装依赖 3、创建编译脚本 4、开始编译 1、源码下载 tslib 源码下载地址: https://github.com/lib…

《动手学深度学习 Pytorch版》 8.4 循环神经网络

8.4.1 无隐状态的神经网络 对于无隐藏装态的神经网络来说&#xff0c;给定一个小批量样本 X ∈ R n d \boldsymbol{X}\in\mathbb{R}^{n\times d} X∈Rnd&#xff0c;则隐藏层的输出 H ∈ R n h \boldsymbol{H}\in\mathbb{R}^{n\times h} H∈Rnh 通过下式计算&#xff1a; …

html和css基础练习

vscode快捷键 alt b 在浏览器中打开 alt shift b 在其他浏览器打开 ctrl / 注释 ctrl y 快捷键删除 参考文章 https://www.bilibili.com/video/BV1m84y1w7Tb 基础html标签 img&#xff1a;图像&#xff0c;title&#xff1a;头部文字&#xff0c;body&#xff1a;主…

格式工厂怎么把两个视频合并在一起

免费的工具谁不喜欢呢&#xff0c;今天为大家介绍的是格式工厂这款多功能视频转换软件&#xff0c;然而今天主要为大家介绍的是格式工厂的视频合并功能。 是的&#xff0c;你没有听错&#xff0c;格式工厂除了转换之外&#xff0c;还可以视频合适、视频剪辑、视频分割、去水印…