免费的app开发工具/小吴seo博客

哈喽,大家好!我是保护小周ღ,本期为大家带来的是Java中自定义类型(对象)的三种比较方式,equals 方法, Comparable 泛型接口, Comparator 泛型接口 。在日常编程中,我们常常会需要比较的问题,那么对于我们的基本数据类型来讲可以直接使用 比较运算符来比较大小(> , < ,== , >= , < =…… ),实际中在Java开发中我们经常使用的是“类”类型,也就是对象,那么作为一个对象又该怎么样去比较数据呢?

一、基本数据类型及Integer包装类的比较
几乎任何一种编程语言都支持基本数据类型比较。

但是对于基本数据来讲,背后还有功能更加强大的包装类,也就是引用类型。
引用类型的数据为什么不能比较呢?首先画个图浅浅的理解一下。
Integer valA = new Integer(10);

为什叫引用类型呢,因为访问数据是通过Java栈区上的引用变量存储的地址来达到访问Java 堆区上对象的数据,可以理解为头在栈区,身体在堆区,只有通过头才能找到身体,引用类型的本质是地址.
那么一块地址值又怎么能够比较?即使可以比较,那么又怎么能达到我们想要的效果呢。
理论上引用类型是不可以比较的,但是有一个特例,就是Integer 包装类。
1.1 包装类的装箱/装包操作
装箱/装包 :把基本数据类型转换成 引用类型(对应的包类型)

在进行自动“装箱”的时候,IDEA会自动调用一个 Integer.valueOf() 方法,来帮我们转换,由这个方法我们可以看到当数值的范围在 [-128, 127] 的范围内存储的是基本数据类型,所以在这个范围内的 Integer 类型的数据是可以直接使用比较运算符比较的。

当数值处在[-128, 127] 的范围内,我们Integer 的底层实际上就是调用数组来存储数据。

如果我们超过这个范围就不行了,原因是变成“引用类型了"。地址是无法比较的。

如果我们直接使用关键字 "new" 来创建一个对象值。

其实也不难想象,这个时候 valA 和 valB 是妥妥的引用类型,即指向对象的地址,他们虽然拥有相同的数值,但是他们指向了不同的两个对象,所以两个地址之间的比较是不可能相同的。我们本质是 期望比较数值 127 的关系,很明显达不到我们的要求。
二、对象的比较
对象的比较有三种比较方式:

2.1 equals 方法
Java 中所有的类都继承于 Object 类,Object 类中提供了一个 equals 方法,但是 equals 方法实际上比较的是引用变量的存储的地址而不是比较的是引用类型引用的对象的内容。
这里是 Object 实现的 equals 方法的实现。
public boolean equals(Object obj) {return (this == obj);
}
this 表示对当前类引用变量的引用,由此可见,实际上还是比较两个地址是否相同。
所以当我们想要判断两个对象是都相同的时候需要重写我们的 equals 方法,按照我们想要的方式来比较对象的内容判断是否相同。
定义一个学生类 Student, 成员变量: Id 学号, name 姓名, age 年龄, sex 性别,并提供一个构造方法
public class Student {public int id; //学号public String name; //姓名public int age; //年龄public String sex; //性别//构造方法public Student(int id, String name, int age, String sex) {this.id = id;this.name = name;this.age = age;this.sex = sex;}@Overridepublic String toString() { //重写toString 方法方便打印展示效果。return "Student{" +"id=" + id +", name='" + name + '\'' +", age=" + age +", sex='" + sex + '\'' +'}';}
}
来到测试类这边 new 两个对象直接使用 equals 方法来比较。

很明显是不相同的,原因是他是直接比较的两个引用类型存储的地址,这两个对象虽然数值相同,但是他们是两个独立的对象,所以比较的返回值就是不相同的。
重写 equals 方法,我们设计当对象之间的成员变量的数值相同,则认为这两个对象相同。
首先我们需要在 Student 类中重写,因为是基于 Student 类比较嘛,子类重写父类方法,子类对象在调用该方法时调用重写后的方法,没有重写的话默认直接调用父类的方法。
快捷键 :Alt + insert

会弹出这个界面,选择 equals() and hashCode, 一路 next 即可。

在每个类中,在重写equals方法的时侯,一定要重写hashcode方法。这是Java官方的语法规定
这里还有一个 hashCode() 方法没有介绍,hashCode 是通过哈希函数计算映射出这个对象的地址,
equals 是基于对象的比较。
面试问题:
equals 比较一样,hashCode 一定一样吗? 一定一样
hachCode 比较一样,equals 一定一样吗? 不一定
为什么呢? hashCode值是依据地址通过某种公式计算来的, 当遇到不同的地址时不能保证计算的结果一定不相同。如果二者是相同的地址,那么通过计算后,得到的hashCode 值是必然相同的。
当只重写equals方法,不重写hashCode时,违反规定:equals相等的对象必须具有相等的哈希码值
总结: 重写equals 方法
如果两个引用指向的是同一个对象,直接返回 true
如果传参的引用指向的为 null ,或者传入的对象所属的类与比较的类不一致返回 false
按照类的这个属性进行比较,例如 Id, name , sex 等相同,那么认为是同一个学生。
String 类型在比较的时候也是调用了 equals 方法,是比较字符串是否相同,String 也是引用类型嘛
涉及到的 Java语法知识:
1.当发生向上转型之后, 此时通过父类的引用只能访问父类自己的成员,不能访问子类特有的成员
2.向上转型后 子类重写的后的方法, 父类调用该方法,此时是调用子类重写后的方法,发生动态绑定
3.动态绑定: 通过父类引用 引用子类对象重写后的方法
4.发生向上转型之后 如果父类引用想使用子类特有的 成员 ,需要进行向下转型(强制类型转换)
5. 向下转型 不安全只能发生在 向上转型 的类型之间, 且右边的范围(父类)大于 左边(子类)
6. 可以用 instanceof 关键字 判断 向下转型是否安全
注意:equals 只能按照相等进行比较,不能按照大于,小于的方式进行比较。

重写 equals 方法后就可以判断 两个对象是否相同了。
2.2 Comparable 接口类的比较
Comparable接口是Java JDK 提供给用户用来实现对象比较的一个泛型接口,然后覆写该接口的一个compareTo 方法,比较的规则就是在该方法定义的,下面我们来看看这个接口的简介:
public interface Comparable<T> {public int compareTo(T o);
}
以上代码可以看到, compareTo 方法的返回值是整型int 数据
返回值 < 0; 表示this 指向的对象小于 o 指向的对象。
返回值 == 0; 表示this 指向的对象等于 o 指向的对象。
返回值 > 0; 表示this 指向的对象大于 o 指向的对象。
我们在面对对自定义类型的时候,如果要想按照大小进行比较时:在定义类时实现Comparable接口即可,然后在类中重写compareTo方法。
如果只是Integer , double 等等基本数据类型之间的比较就可以直接实现该接口然后调用 compareTo() 方法。
以Student 类为例:
public class Student implements Comparable<Student>{public int id; //学号public String name; //姓名public int age; //年龄public String sex; //性别//构造方法public Student(int id, String name, int age, String sex) {this.id = id;this.name = name;this.age = age;this.sex = sex;}/*** 重写 compareTo 方法,博主设计 按照 id 来比较数据从而判断对象的大小* @param o* @return*/@Overridepublic int compareTo(Student o) {return this.id - o.id;}@Overridepublic String toString() { //重写toString 方法方便打印展示效果。return "Student{" +"id=" + id +", name='" + name + '\'' +", age=" + age +", sex='" + sex + '\'' +'}';}
}



可以看到,对象之间就可以根据我们的需求来比较对象之间的大小,博主首先设计的是 采用 id 作为 关键字来比较,但是如果我们想要采用姓名 或者是 年龄 等等来作为关键字来比较对象的大小,我们就需要修改compareTo 方法的比较方式。
如果我们采用name 来比较数据:
/*** 重写 compareTo 方法,博主设计 按照 name 来比较数据从而判断对象的大小* @param o* @return*/@Overridepublic int compareTo(Student o) {if(this.name.compareTo(o.name) == 0) { //字符串的比较 调用 String 的 compareTo 方法return 0;} else if (this.name.compareTo(o.name) < 0) {return -1;} else {return 1;}//为了方便理解所以上面写的复杂,按照下面的方式更好/*return o1.name.compareTo(o2.name);*/}
关于String 类型的对象的比较,我们也可以使用 String 类下的 compareTo 方法我们来看看 JDK 是如何实现这个方法的:
public int compareTo(String anotherString) {int len1 = value.length;int len2 = anotherString.value.length;int lim = Math.min(len1, len2);char v1[] = value;char v2[] = anotherString.value;int k = 0;while (k < lim) {char c1 = v1[k];char c2 = v2[k];if (c1 != c2) {return c1 - c2;}k++;}return len1 - len2;}
首先计算两个字符串的长度,转换成字符数组,拿最小的lim字符长度来遍历字符串,在lim 范围内比较,如果字符不相同就返回 两个字符 ASCll 的差值,如果在 lim 的范围内字符都相同,则返回两个字符串长度的差值。
总结:
1.我们想要按照某个关键字来比较对象之间大小的关系,我们可以让实现 Comparable 接口,然后根据实际环境的需要重写compareTo 方法。
2. 使用Comparable 接口来比较对象之间的大小的关系的时候,我们一般是 写死compareTo 方法,无法灵活的更改关键字来达到更改对象比较的方式。比如说我们的通讯录,可以按照我们的姓氏首字母来排序,也可以根据修改日期,可以根据号码排序,我们使用 compareTo 方法比较岂不是每次都要修改源代码?这是不现实的,那怎么办呢,接下来会讲。
3. Comparable 是 Java.lang 中的接口类,可以直接使用。
2.3 Comparator 接口(基于比较器比较)
使用这个接口需要我们自己定义一个比较器类然后实现 Comparator泛型接口,再重写 compare() 方法。
class idComparator implements Comparator<Student>{ //通过学号来比较大小@Overridepublic int compare(Student o1, Student o2) {return o1.id - o2.id;}
}
兄弟们注意:Comparator 跟 Comparable 的区别。
class idComparator implements Comparator<Student> { //通过学号来比较大小@Overridepublic int compare(Student o1, Student o2) {return o1.id - o2.id;}
}class nameComparator implements Comparator<Student> { //通过姓名来比较大小@Overridepublic int compare(Student o1, Student o2) {if(o1.name.compareTo(o2.name) == 0) { //字符串的比较 调用 String 的 compareTo 方法return 0;} else if (o1.name.compareTo(o2.name) < 0) {return -1;} else {return 1;}}
}public class Test3 {public static void main(String[] args) {Student student1 = new Student(202300,"李三",19,"男");Student student2 = new Student(202301,"张四",19,"男");idComparator idComparator = new idComparator(); //按照 id 来比较System.out.println(idComparator.compare(student1, student2));nameComparator nameComparator = new nameComparator();// l 在 z 的前面嘛,所以返回的是 1;System.out.println(nameComparator.compare(student1, student2)); }
}

采用这种方式我们才可能实现关键字随需变换的机制,但是还有一点问题,就是我们我们虽然写了很多比较类,但是我们怎么做到在Student类外传入比较器,从而改变Student类内部的比较方式呢?
如果我们在 Student 类的内部需要比较的形式,要求是通过类外影响Student 类的比较机制。
首先我们在 Student 类的内部既然需要比较那肯定涉及到方法,我们就可以对比较的方法入手,如果将比较器以传参的形式输入,那么类方法就在内部拿到比较器,从而通过传参的比较器从而达到计较的目的。
现在摆在我们眼前的是如何接收比较器对象,因为我们的需求是可以接收多个比较器对象。
以该比较器为例:
class idComparator implements Comparator<Student>{ //通过学号来比较大小@Overridepublic int compare(Student o1, Student o2) {return o1.id - o2.id;}
}
我们使得 idComparator 类继承了Comparator<Student> 的泛型接口,然后我们重写了接口的 compare() 方法,两个Student对象参数根据我们设计的某种机制比较大小,返回 int 类型的数据。
所以我们可以采用 Comparator 接口来接收(Student)泛型对象。
接口作为方法的参数,可以接收该接口的所有实现类的对象
接口作为方法的返回值,可以返回该接口的所有实现类的对象
JDK 关于这方面的实现是使用 Comparator<? super T> 来接收比较器对象。
Comparator<? super T> 代表任意T的父类或祖先,Comparator<? super Student>可以表示接受任意一个泛型类型是Student父类的Comparator,比如一个Comparator<Person>可以给所有Person(人)比较,那么自然也可以给Student比较。
? 是通配符表示可传入的类型不确定,通常需要限制一下范围,super T就是限定条件,表示 ?只能接收T类型及其父类型。 T 类型此时是接收了 Student 类型。
? extends T:可以接收T类型或者T类型的子类,泛型的上限
? super T:可以接收E类型或者E的父类型, 泛型的下限
话不多说直接上代码:
/*** 冒泡排序 从小到大排序* @param stu* @param c* @return*/public static <T> T[] bubbleSort(T[] stu, Comparator<? super T> c) {if(stu == null || c == null) {return stu;}for (int i = 0; i < stu.length - 1; i++) {for (int j = 1; j < stu.length - i; j++) {if(c.compare(stu[j - 1],stu[j]) > 0) {T tmp = stu[j - 1];stu[j - 1] = stu[j];stu[j] = tmp;}}}return stu;}
为了方便理解博主简单的写了一个冒泡排序,然后该方法是静态方法,可以直接使用类名调用,静态的泛型方法需要声明一下类型 <T>。

可以看到非常的成功,如果我们想要根据姓名来排序,直接new 一个我们设计的name类来作为参数即可。

总结:
1. equals 适用于比较两个对象之间的相等于否。
2. Comparable 泛型接口 适用于类的内部比较,如果想要对自定义对象按照某种方式来进行比较,则需要该类需要实现 Comparable 接口,并重写 compareTo() 方法,这种情况下比较方式基本上是写死的。
3. Comparable 泛型接口 适用于自定义类型的灵活比较,需要自己选择比较器对象,提供比较器类,可以在类的内部,也可以在类的外部传参比较器,这个需要根据自己的设计和需求来,使用该接口需要重写 compare() 方法。
至此,Java 的对象的比较博主已经分享完了,希望对大家有所帮助,如有不妥之处欢迎批评指正。

本期收录于博主的专栏——JavaSE,适用于编程初学者,感兴趣的朋友们可以订阅,查看其它“JavaSE基础知识”。
感谢每一个观看本篇文章的朋友,更多精彩敬请期待:保护小周ღ *★,°*:.☆( ̄▽ ̄)/$:*.°★*
do
cc即撒后看来大家了类
。
相关文章:

【JavaSE】对象的比较
哈喽,大家好!我是保护小周ღ,本期为大家带来的是Java中自定义类型(对象)的三种比较方式,equals 方法, Comparable 泛型接口, Comparator 泛型接口 。在日常编程中,我们常常会需要比较的问题&…...

Leetcode DAY 49~50:买卖股票的最佳时机 1 2 3 4
121. 买卖股票的最佳时机 1、贪心算法 class Solution { public:int maxProfit(vector<int>& prices) {//贪心int low INT_MAX;int res 0;for(int i 0; i < prices.size(); i) {low min(low, prices[i]); //左最小价格res max(res, prices[i] - low); //当前…...

Android Handler机制(二) Handler 实现原理
一. 前言 接上一篇文章为什么设计Handler , 我们来继续讲解一下Handler的实现原理, 俗话说一个好汉三个帮, 接下来一步一步引入各个主角,并说明它们在Handler机制中扮演的角色和作用. 二. Handler实现原理 首先我们先确定一个结论: 使用 Handler 是希望它被实例化在哪个线程&a…...

Elasticsearch教程(19) 详解mapping之keyword
Elasticsearch已升级,新版Elasticsearch keyword博客参考下面这篇【Elasticsearch教程8】Mapping字段类型之keyword_elasticsearch的keyword_亚瑟弹琴的博客-CSDN博客 1 前言 本文基于ES7.6,如果是之前版本,是有区别的。 ES支持的字段类型很…...

LeetCode算法复杂度分析(时间复杂度空间复杂度)
文章目录前言时间复杂度1.概述2.大O记法3.常见类型空间复杂度1.概述2.常见类型典型算法的复杂度分析1.递归算法2.哈希表前言 我们知道,研究算法的最终目的就是如何花更少的时间,如何占用更少的内存去完成相同的需求。 时间复杂度 1.概述 我们要计算算…...

Android OpenCV(七十三):吊打高斯模糊的StackBlur Android 实践
前言 OpenCV 4.7.0 2022年12月28日Release,ChangeLog中提到 Stackblur algorithm implementation. Stackblur是一种高斯模糊的快速近似,由Mario Klingemann发明。其计算耗时不会随着kernel size的增大而增加,专为大kernel size的模糊滤波场景量身定制。 使用建议:当kerne…...

4.排序算法之一:冒泡排序
排序算法稳定性假定在待排序的记录序列中,存在多个具有相同的关键字的记录,若经过排序,这些记录的相对次序保持不变,即在原序列中,r[i]r[j],且r[i]在r[j]之前,而在排序后的序列中,r[…...

python自学之《21天学通Python》(16)——第19章 用Pillow库处理图片
Pillow是Python2.X时代比较流行的Python ImagingLibrary(简称Pillow)图像处理库的分支,并修复了一些bug。Pillow提供了对Python3的支持,为Python3解释器提供了图像处理的功能。和Pillow库一样提供了广泛的文件格式支持、高效的内部…...

发布依赖到maven仓库
maven中央仓库是一个开放的仓库,所以我们也可以把自己开发的jar推送到远程仓库,这样可以直接引入pom依赖使用我们的库。 准备工作 ● 需要一个github账号(程序员必备) ● 网络代理(涉及到的网站通常没版本在国内直接访…...

Laravel-admin之自定义操作日志
laravel-admin是封装性极好的框架,自带的就有操作日志的记录,但是对于非开发人员可能看不懂这个日志,所以就想着给修改一下,以谁修改了什么,谁删除了什么,谁审核了什么,谁添加了什么类似&#x…...

用Python做了一个法律查询小工具,非常好用
用Python做了一个法律查询小工具,非常好用效果展示准备工作不会的话可以点我直达代码和视频讲解,我都准备好了主要代码哈喽兄弟,今天给大家分享一个Python tkinter制作法律查询小工具。 光爬虫大家也只能自己用用,就算打包了exe&…...

工作篇:触摸屏原理介绍
一、触摸屏概述 触摸屏作为一种新的输入设备,它是目前最简单、方便、自然的一种人机交互方式。 当接触了屏幕上的图形按钮时,屏幕上的触觉反馈系统可根据预先编程的程式驱动各种连结装置,可用以取代机械式的按钮面板,并借由液晶…...

Ep_操作系统面试题-操作系统的分类
答案 单体系统 整个操作系统是以程序集合来编写的,链接在一块形成一个二进制可执行程序,这种系统称为单体系统。 分层系统 每一层都使用下面的层来执行其功能。 微内核 微内核架构的内核只保留最基本的能力,把一些应用放到了用户空间 客户-…...

iframe或document监听滚动事件不起作用
有时候我们会遇到监听iframe或document的滚动事件不起作用的情况,在排除代码写错的情况下,我们应该考虑此时的document是否可以滑动。 1、为什么document不能监听滑动? 就很奇怪,明明页面时有滚动条的,为什么说document不可滑动…...

基频估计算法简介
基频估计算法 F0 estimate methods 估计F0的方法可以分为三类:基于时域、基于频域、或混合方法。本文详细介绍了这些方法。 所有的算法都包含如下三个主要步骤: 1.预处理:滤波,加窗分帧等 2.搜寻:可能的基频值F0(候选…...

linux修改DNS 系统版本Kylin V10桌面版
配置DNS在银河麒麟桌面操作系统V10 SP1 中修改DNS信息,直接修改/etc/resolv.conf文件中的DNS信息,不能生效。应该参考如下步骤:一、首先修改 /etc/systemd/resolved.conf文件,在其中添加DNS信息在终端中执行以下命令:s…...

如何使用 AWS Lambda 运行 selenium
借助 AWS Lambda 运行 selenium 来爬取网络数据。 简介 与手动从网站收集数据相比,爬虫可以为我们节省很多时间,对于爬虫的每次请求而言,这相当于 AWS Lambda 的每次函数的运行。 AWS Lambda 是一种将脚本部署到云的简单且价格低廉的服务&…...

认识Cesium旋转大小变量
前文代码中有如下;矩阵乘以旋转大小,还放入mat; Cesium.Matrix4.multiply(mat, rotationX, mat); 初看以为rotationX是一个数值,因为矩阵可以和数相乘; 但是看它的代码,rotationX是由一长串代码获得的&a…...

异响加持、吐槽声不断,小鹏G9难解困局
小鹏汽车的烦恼就好比红尘中的三千青丝,小鹏G9“惊魂48小时”的恐慌还未平息,车门异响等问题就已经层出不穷,再次将小鹏汽车推上风口浪尖。 可以毫不客气的说,G9承载着小鹏汽车盈利的希望,但在原本处于上升之势的G9却…...

【react】react18的学习
一、安装 $ create-react-app [Project name]默认支持sass 二、核心依赖 react:react 核心 react-dom:用于开发渲染web 应用; react-scripts:封装webpack服务; "start": "react-scripts start&quo…...

Ep_操作系统面试题-什么是线程,线程和进程的区别
1. 一个进程中可以有多个线程,多个线程共享进程的堆和方法区 (JDK1.8 之后的元空间),但是每个线程有自己的程序计数器、虚拟机栈和 本地方法栈。 2.进程是资源分配的最小单位,线程是CPU调度的最小单位 视频讲解: https://edu.csdn.net/course/detail/38090 点我…...

最流行的自动化测试工具,总有一款适合你(附部分教程)
前言 在自动化测试领域,自动化工具的核心地位毋庸置疑。本文总结了最顶尖的自动化测试工具和框架,这些工具和框架可以帮助组织更好地定位自己,跟上软件测试的趋势。这份清单包含了开源和商业的自动化测试解决方案。 1)Selenium …...

Shell高级——进程替换vs管道
以下内容源于C语言中文网的学习与整理,如有侵权请告知删除。 1、问题引入 这里将Shell中的“进程替换”与“管道”放在一起讲,是因为两者的作用几乎类似。 进程替换:将一个命令的输出结果传递给另一个(组)命令。 管…...

国内有哪些支持定制化的低代码平台?
编者按:贴合企业业务需求的系统才是好系统,高程度的定制能力平台意味着可以提供更高契合度的产品,更好地匹配业务需求。本文介绍了国内支持定制化的老厂商低代码平台,具有源码交付、私有化部署、国产化、数据对接等优势。关键词&a…...

Altair 宣布将于3月举办 Future.Industry 2023 全球虚拟大会
Altair(纳斯达克股票代码:ALTR)近日宣布将于 2023 年 3 月 8 - 9 日 举办年度全球虚拟大会 Future.Industry 2023。旨在探索影响全球未来的新趋势,并深入探讨仿真、高性能计算 (HPC)、人工智能(AI)和数据分…...

react lazyLoad学习记录
react lazyLoad学习记录1.lazyLoad用处2.使用2.1 react-router-dom5版本写法2.2 react-router-dom6版本写法1.lazyLoad用处 默认例如首页,如果有好十几个甚至百个路由,react是会默认一下全部把路由组件一下全部加载的,极可能造成页面卡顿。r…...

29 openEuler管理网络-配置网络绑定
文章目录29 openEuler管理网络-配置网络绑定29.1 使用nmcli29.2 使用命令行29.2.1 检查是否已安装Bonding内核模块29.2.2 创建频道绑定接口29.2.3 创建从属接口29.2.4 激活频道绑定29.2.5 创建多个绑定29 openEuler管理网络-配置网络绑定 29.1 使用nmcli 创建名为bond0的绑定&…...

RTT 全志D1s RDC2022纪念版开发板开箱使用分享与折腾记录
原文链接:https://bbs.aw-ol.com/topic/3021/ 作者caoxuetian 1:开发板介绍 RTT D1s RDC2022纪念版开发板是一块基于全志科技RISC-V内核 芯片 D1S的小尺寸开发板,尺寸仅为5.5cm*4cm,能够已非常小的体积带来舒适的开发感受&#…...

24日常实习万得一面面径
文章目录分析与复盘面试题分析与复盘 应该将项目进行复习好的,两个项目都应该对简历写的那些进行复习,以为日常不问项目的一面。哭死… 面试题 1.自我介绍 2.为什么从土木转到开发,学习java有哪些途径 3.介绍下项目中你觉得最有设计的模…...

MySQL的DML和DDL操作(1)
这里介绍几种DML操作INSERT INTO——插入记录插入一条记录插入一条记录 INSERT INTO table [(column [, column . ])] VALUES(value [,value . ]); 例子: insert into student values( 1,"承太郎" )default charset utf8;插入多条记录插入多条…...