【Java SE】对象的比较

🥰🥰🥰来都来了,不妨点个关注叭!
👉博客主页:欢迎各位大佬!👈

在这里插入图片描述
本期内容满满干货,将会深入介绍对象与对象之间是如何进行比较的,我们知道基本数据类型是可以直接比较大小的,Java中引用类型的变量不能直接按照大于或者小于的方式进行比较,那为什么==可以比较呢?我们一起带着这些问题来了解本期内容

文章目录

  • 1. 等于关系
    • 1.1 ==
    • 1.2 equals方法
    • 1.3 ==和equals方法的区别
  • 2. 大于/小于关系
    • 2.1 实现Comparable接口
    • 2.2 Comparator比较器
    • 2.3 三种重写方法的比较

1. 等于关系

==可以比较引用数据类型的原因
对于用户实现自定义类型,都默认继承Object类,Object类中提供equals方法,==默认情况下调用的就是equals方法,该方法的比较规则是:不是比较引用变量引用对象的内容,而是直接比较引用变量的地址,但有些情况下该种比较就不符合题意,这时就需要重写equals方法,达到我们的目的
Object中equals的实现,可以清楚的看到,直接比较的是两个引用变量的地址

 public boolean equals(Object obj) {return (this == obj);}

1.1 ==

class Person {public String name;public String gender;public int age;Person(String name,String gender, int age) {this.name = name;this.gender = gender;this.age = age;}public String toString() {return "[" + this.name + ":" + this.gender + " "+ this.age + "]";}
}public class Test {public static void main(String[] args) {//1,==比较基本数据类型int a = 10;int b = 10;System.out.println(a == b);//2. ==比较引用数据类型Person[] person = new Person[] {new Person("泡泡","女",19),new Person("泡泡","女",19),new Person("柚柚","女",25),new Person("球球","男",25)};System.out.println(person[0] == person[1]);System.out.println(person[0].equals(person[1]));}}

打印结果为:
在这里插入图片描述\

1.2 equals方法

有些情况下,需要比较的是对象中的内容,这时需要重写equals方法,比如上述例子,我们可以看到person[0]与person[1]这两个对象的内容都是一样的,所以我们希望equals方法比较的时候返回的是true

class Person {public String name;public String gender;public int age;Person(String name,String gender, int age) {this.name = name;this.gender = gender;this.age = age;}public String toString() {return "[" + this.name + ":" + this.gender + " "+ this.age + "]";}@Overridepublic boolean equals(Object o) {//自己和自己比较if(this == o) {return true;}//o是null对象或者o不是Person类if(o == null || !(o instanceof Person)) {return false;}Person p = (Person)o;//基本数据类型如age为int类型可以直接用==比较//引用类型最好还是用equals比较return name.equals(p.name) && gender.equals(p.gender) && age == p.age;}
}public class Test {public static void main(String[] args) {//比较引用数据类型Person[] person = new Person[] {new Person("泡泡","女",19),new Person("泡泡","女",19),new Person("柚柚","女",25),new Person("球球","男",25)};System.out.println(person[0] == person[1]);System.out.println(person[0].equals(person[1]));}}

打印结果如下:
在这里插入图片描述
因为==实际上还是调用的默认equals方法,对象的地址进行比较,所以打印false,而重写了equals后,再进行比较,我们看到person[0]与person[1]的内容完全一致,所以返回true

equals方法覆写的通用步骤:

  1. 如果指向同一个对象,返回 true
  2. 如果传入的为 null或者传入的对象类型不是该类的,返回false
  3. 按照自己的规则,完成类的实现目标比较
  4. 注意在重写的时候用其他引用类型的比较也需要 equals,例如这里的name,gender的比较

缺点】equals方法只能比较是否相等,不能按照大于、小于的方式进行比较

1.3 ==和equals方法的区别

==
对于基本数据类型,比较的是值
对于引用数据类型,比较的是对象的内存地址

因为Java只有值传递,所以,==不管是比较基本数据类型还是引用数据类型变量, 其本质比较的都是值,只是引用类型变量存的值是对象的地址

equals方法
equals方法比较的也是对象的内存地址,但是可以重写equals,按照自己的比较规则来比较内容是否相等

2. 大于/小于关系

下面我们来看看这个例子,给一个对象数组排序,能否直接用已经有的sort方法呢~

class Person {public String name;public String gender;public int age;Person(String name,String gender, int age) {this.name = name;this.gender = gender;this.age = age;}public String toString() {return "[" + this.name + ":" + this.gender + " "+ this.age + "]";}}
public class Test1 {public static void main(String[] args) {Person[] person = new Person[] {new Person("泡泡","女",19),new Person("西西","男",33),new Person("柚柚","女",25),new Person("球球","男",25)};Arrays.sort(person);System.out.println(Arrays.toString(person));}
}

运行结果:运行出错,抛出异常
在这里插入图片描述
答案是显然不行的,因为整数之间是可以直接比较,大小关系明确。但是两个学生对象的大小关系无法确定,需要我们自己额外指定,下面介绍两种方法:

2.1 实现Comparable接口

即Person类实现Comparable接口,并重写该接口的compareTo方法
Comparble是JDK提供的泛型的比较接口类,T代表泛型,实现过程具体如下:

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

在这里插入图片描述
(一) 以下为使用Comparable接口,按上述例子,年龄进行从大到小排序的代码:

class Person implements Comparable{public String name;public String gender;public int age;Person(String name,String gender, int age) {this.name = name;this.gender = gender;this.age = age;}public String toString() {return "[" + this.name + ":" + this.gender + " "+ this.age + "]";}public int compareTo(Object o) {Person p = (Person)o;if(this.age > p.age) {return -1;}else if(this.age < p.age) {return 1;}else {return 0;}//上述判断可以直接写成//return p.age - this.age; //该两个对象比较打印结果为年龄差值}}
public class Test1 {public static void main(String[] args) {Person[] person = new Person[] {new Person("泡泡","女",19),new Person("西西","男",33),new Person("柚柚","女",25),new Person("球球","男",25)};//两个对象的比较System.out.println(person[0].compareTo(person[1]));//对象数组排序Arrays.sort(person);System.out.println(Arrays.toString(person));}
}

运行结果如下:
在这里插入图片描述
解释说明
(1) 表达当前对象大于参数对象
在这里插入图片描述
(2) 在sort方法中会自动调用compareTo方法,compareTo的参数是Object,其实传入的是Person类型的对象,比较当前对象与参数对象的大小关系,可以自己定义比较哪个参数(比如这里按年龄来算的)

1> 如果当前对象应排在参数对象前,返回小于0的数字
2> 如果当前对象应排在参数对象后,返回大于0的数字
3> 如果当前对象与参数对象不分先后,返回0

(3) 如果想让年龄从小到大排序呢~即把大于号改成小于号,小于号改成大于号,记住想让当前对象排在参数对象前,返回值需要小于0

 public int compareTo(Object o) {Person p = (Person)o;if(this.age < p.age) {return -1;}else if(this.age > p.age) {return 1;}else {return 0;}}
 public int compareTo(Object o) {Person p = (Person)o;return this.age - p.age;}

(二) 以下为使用Comparable接口带泛型的代码:

class Person implements Comparable<Person>{public String name;public String gender;public int age;Person(String name,String gender, int age) {this.name = name;this.gender = gender;this.age = age;}public String toString() {return "[" + this.name + ":" + this.gender + " "+ this.age + "]";}public int compareTo(Person o) {return this.age - o.age;}}
public class Test1 {public static void main(String[] args) {Person[] person = new Person[] {new Person("泡泡","女",19),new Person("西西","男",33),new Person("柚柚","女",25),new Person("球球","男",25)};System.out.println(person[0].compareTo(person[1]));Arrays.sort(person);System.out.println(Arrays.toString(person));}
}

打印结果如下:年龄按从小到大排序
在这里插入图片描述
缺点】容易写死,写死就固定下来了~
总结即可以在一个类中实现Comparable接口,并实现该接口的方法comparaTo方法,可按照自己指定规则,进行比较排序

2.2 Comparator比较器

按照比较器比较的方式具体步骤如下:
(1) 用户自定义比较器类,实现Comparator接口

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

在这里插入图片描述
(2) 重写Comparator中的compare方法,上述例子代码如下:

import java.util.Comparator;class Person implements Comparable<Person>{public String name;public String gender;public int age;Person(String name,String gender, int age) {this.name = name;this.gender = gender;this.age = age;}public String toString() {return "[" + this.name + ":" + this.gender + " "+ this.age + "]";}@Overridepublic int compareTo(Person o) {return this.age-o.age;}
}class PersonAgeComparator implements Comparator<Person> {@Overridepublic int compare(Person o1, Person o2) {return o2.compareTo(o1);}
}public class Test2 {public static void main(String[] args) {Person[] person = new Person[] {new Person("泡泡","女",19),new Person("西西","男",33),new Person("柚柚","女",25),new Person("球球","男",25)};//定义比较器对象PersonAgeComparator tor = new PersonAgeComparator();//使用比较器对象进行比较System.out.println(tor.compare(person[0],person[1]));}
}

运行结果:
在这里插入图片描述注意
(1) Comparator是java.util 包中的泛型接口类,使用时必须导入对应的包,即import java.util.Comparator;
(2) 这里不能直接使用Arrays.sort来排序对象数组,因为没有重写compareTo方法,sort方法中会自动调用compareTo方法

2.3 三种重写方法的比较

在这里插入图片描述💛💛💛本期内容回顾💛💛💛
在这里插入图片描述✨✨✨本期内容到此结束啦~下期再见!

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

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

相关文章

厦门网上在线教育系统,线下老师怎么转型到线上网上授课?

现在很多 线下老师都想转到线上做网课&#xff0c;但是在转线上过程中会出现很多问题&#xff0c;很多人都不知道怎么开始&#xff0c;今天小编和大家说一下要注意的。 一、你要有一套适合线上的教学视频 首先你要准备做的课程内容是什么&#xff0c;怎么讲&#xff0c;讲什么&…

[Linux]如何在Ubuntu 22.04系統安裝Node-red?

Node-red是一個建立在Node.js上的視覺化程式設計工具&#xff0c;其常見的應用情境為建置或轉換各項硬體之間的通信協定的物聯網或工聯網場域&#xff0c;其可藉由設置來安裝第三方應用模組來建置多樣的通信協定節點&#xff0c;包含modbus in/out, mqtt in/out, websocket in/…

Mac YOLO V9推理测试

环境&#xff1a; Mac M1 (MacOS Sonoma 14.3.1) Python 3.11PyTorch 2.1.2 一、准备工作 工程及模型下载&#xff1a;​​​​​​​https://github.com/WongKinYiu/yolov9 git clone https://github.com/WongKinYiu/yolov9.git 克隆后安装相关依赖&#xff08;没啥依赖好装…

力扣:416. 分割等和子集(Java,动态规划:01背包问题)

目录 题目描述&#xff1a;示例 1&#xff1a;示例 2&#xff1a;代码实现&#xff1a; 题目描述&#xff1a; 给你一个 只包含正整数 的 非空 数组 nums 。请你判断是否可以将这个数组分割成两个子集&#xff0c;使得两个子集的元素和相等。 示例 1&#xff1a; 输入&#…

容器集群管理系统Kubernetes(K8S)

目录 一、前言 1.1什么是云原生&#xff1f; 1.2云要素的四要素&#xff1f; 1.2.1微服务 1.2.2容器化 1.2.3DevOps 1.2.4持续交付 1.3云平台有哪些&#xff1f; 1.4SRE 二、Kubernetes 概述 2.1K8S 是什么 2.2K8S作用 2.3K8S版本 2.4为什么要用 K8S 2.5K8S 的特…

在Ubuntu上安装Anaconda之后,启动失败

为了方便管理Pythonu环境&#xff0c;在Ubuntu的Docker容器中安装了Anaconda&#xff0c;安装完成&#xff0c;启动时出现如下错误&#xff1a; conda activate xxx usage: conda [-h] [--no-plugins] [-V] COMMAND ... conda: error: argument COMMAND: invalid choice: acti…

如何让加快OpenHarmony编译速度?

OpenHarmony 有两种编译方式&#xff0c;一种是通过 hb 工具编译&#xff0c;一种是通过 build.sh 脚本编译。本文笔者将提升 build.sh 方式编译速度的方法整理如下&#xff1a; 因为笔者只用 build.sh 脚本编译&#xff0c;没用过 hb 工具&#xff0c;好像下面的选项也可以用于…

RockChip Uboot/Kernel开机LOGO和Android开机动画

一:Uboot/Kernel开机LOGO 1、默认替换方式 uboot和kernel阶段的logo分别为开机显示的第一张和第二张图片,可通过替换logo文件,重新编译内核的方法修改uboot和kernel开机logo,编译后的logo文件位于boot.img中。 uboot logo文件:kernel/logo.bmp kernel logo文件:kernel/…

Jenkins--自动化构建和部署SpringBoot项目

一、实现目标 通过在Jenkins中创建流水线任务&#xff0c;编写流水线脚本以实现自动化构建和部署SpringBoot项目。流水线脚本主要实现以下几个步骤&#xff1a; Preparation&#xff1a;从gitee上拉取远程仓库的SpringBoot项目代码。Build&#xff1a;使用Maven对拉取的代码进…

部署JVS服务出现上传文件不可用,问题原因排查。

事情的起因是这样的&#xff0c;部门经理让我部署一下JVS资源共享框架&#xff0c;项目的地址是在这里 项目资源地址 各位小伙伴们做好了&#xff0c;我要开始发车了&#xff0c;全新的“裂开之旅” 简单展示一下如何部署JVS文档 直达链接 撕裂要开始了 本来服务启动的好好…

链式二叉树的基本操作1

1.概念回顾 讲二叉树的基本操作之前&#xff0c;我们回顾一下二叉树的概念 在讲树之前&#xff0c;我们的每讲一种数据结构&#xff0c;无外乎就是在讲它们的增删查改&#xff0c;但是在树这里&#xff0c;就有了不小变化。 2.结点的定义 既然是链式二叉树&#xff0c;那必须…

奇安信网络安全实习一面

自我介绍数据库的几种防御方式&#xff0c;无回显怎么办&#xff1f;防御最有效的方式&#xff0c;预编译的原理&#xff1f;应急的经验&#xff08;在之前实习公司&#xff09;redis未授权怎么getshellmysql怎么获取shell做过代码审计嘛&#xff1f;java721没有链怎么办&#…

在线企业机构不可错过的开源知识付费平台!免费试用!,免费网上教学平台有哪些?怎么选择?

在线教育平台可谓如雨后春笋般&#xff0c;一个接一个的诞生。当然&#xff0c;对于学员来说&#xff0c;找在线教学平台首先是找对自己有用的&#xff0c;再者就是免费平台。其实在线教学平台免费的也有&#xff0c;不过不是每个课程都免费。这里我们一起来看看免费的在线教育…

部署 Sentinel 控制台:实现流量管理和监控

序言 Sentinel 是阿里巴巴开源的一款流量防护与监控平台&#xff0c;它可以帮助开发者有效地管理微服务的流量&#xff0c;实现流量控制、熔断降级、系统负载保护等功能。本文将介绍如何在项目中部署和配置 Sentinel 控制台&#xff0c;实现微服务的流量防护和监控。 一、Sen…

机器学习_如何给客户做聚类K-Means

文章目录 前言K-Means 的工作原理总结K-Means的实战 前言 在工作中遇见咱们给客户做下聚类&#xff0c;划分下客群&#xff0c;这里分成3类&#xff08;也可根据需求分成6类&#xff09;。根据现有的字段&#xff0c;将数值分成层级&#xff08;已处理好的数据&#xff09;&am…

深入理解Linux中TCP/IP协议栈的实现原理与具体过程

一、Linux内核与网络体系结构 在我们了解整个linux系统的网络体系结构之前&#xff0c;我们需要对整个网络体系调用&#xff0c;初始化和交互的位置&#xff0c;同时也是Linux操作系统中最为关键的一部分代码-------内核&#xff0c;有一个初步的认知。 1、Linux内核的结构 …

智能改写文章怎么做,3个方法让你轻松改出高质量文章

在如今的自媒体兴盛时代&#xff0c;内容创作对于自媒体人来说是必不可少的一项工作&#xff0c;然而&#xff0c;如何在保持内容原创性的前提下迅速生成高质量的文章变得尤为重要。智能改写文章的出现&#xff0c;为所有的自媒体人带来了一种全新的思路&#xff0c;它让大家在…

2024付费进群系统,源码及搭建变现视频课程(教程+源码)

前三节讲解搭建支付对接&#xff0c;后两节讲解一些引流变现的方法&#xff0c;还有一种变现就是帮人搭建这样的平台&#xff0c;因为全网都没有一套完整的视频教怎么搭建的&#xff0c;有也只是文字教程&#xff0c;一般新人根本看不懂&#xff0c;我视频实操演示&#xff0c;…

16-LINUX--线程安全

一。线程安全 线程安全即就是在多线程运行的时候&#xff0c;不论线程的调度顺序怎样&#xff0c;最终的结果都是 一样的、正确的。那么就说这些线程是安全的。 要保证线程安全需要做到&#xff1a; 1&#xff09; 对线程同步&#xff0c;保证同一时刻只有一个线程访问临界资…

Java Excel操作

Apache POI是一个用于读写Microsoft Office文件格式的Java库&#xff0c;可以用来读取或写入Excel文件。 使用步骤 1.导入坐标 <!--alibaba-fastjson--> <dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId>…