equals方法相关总结
先说一下Object类吧:
这是一个号称为祖宗类的东西,是所有类的父类,也是唯一一个没有父类的类。
接口不继承object类
并且Object类存在于java的lang包中,我们都知道存在于lang包中的类我们是可以直接使用的,后面总结的也都是这方面的
今天说一下Object类中的equals方法吧
对于这个方法的总结最先有些懵,借鉴了https://www.cnblogs.com/dolphin0520/category/361055.html这个大神写的一些东西,受益很大,在重写了一些equals方法后也算是彻底掌握了
一.其源码
public boolean equals(Object obj) {
return (this == obj);
}
二.该方法和“==”的区别
这是来自于《java编程思想》的一段原话:
“关系操作符生成的是一个boolean结果,它们计算的是操作数的值之间的关系”
简单来说“==”是用来判断两个变量之间是否相等。
equals方法是用来比较地址是否相同的(我们根据上面的源码来解释一下吧)
this==obj obj是我们传过来的对象地址,this存放的是本类对象的地址
public class Main {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
int n=3;
int m=3;
System.out.println(n==m);
String str = new String("hello");
String str1 = new String("hello");
String str2 = new String("hello");
System.out.println(str1==str2);
str1 = str;
str2 = str;
System.out.println(str1==str2);
}
}
结果: true
false
true
对于第一个结果相信我们都知道是为什么:因为他直接比较的数值的值是否相等3==3所以返回值一定是true。
对于第二个结果就会有些不理解了:上面不是说“==”比较的是数值是否相同吗? 在这里我们应该了解到引用类型的变量存的并不是数值,他们存的是每一个对象的地址,我们每实例化一个对象就会在堆中重新创建一个对象,其地址不一样. 所以这里因为地址不一样所以返回值为false。
那么对于第三个结果就很好解释了:我们使str1,str2地址相等,所以返回值一定是true。
所以从这里可以看出来“==”比较的是具体数值,但就看你变量存的是啥数值了,可能是地址,或者一个值之类的。
三.通过一个代码来说明一些问题
public class Main {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
String str1 = new String("hello");
String str2 = new String("hello");
System.out.println(str1.equals(str2));
}
}
结果:true
四.对于上面问题的解释
我们上面说了equals方法比较的是地址,实例化之后地址一定不一样了.但为什么上面程序结果是true
我们应该知道Object是所有类的父类,String类也不例外.可是身为子类,总得有点特权吧(要不然这爹白叫了),没错重写方法,因为在String类中重写了equals方法,所以比较的就不再是地址了,而是传过去的参数.
至于他是怎样比较的,我在下面会将我的比较自己写的简陋但易懂的重写方法写出来
现在这里是java中String类中equals方法的重写
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String anotherString = (String)anObject;
int n = value.length;
if (n == anotherString.value.length) {
char v1[] = value;
char v2[] = anotherString.value;
int i = 0;
while (n-- != 0) {
if (v1[i] != v2[i])
return false;
i++;
}
return true;
}
}
return false;
}
五.我重写的equals方法
public class NewLife {
private int age;
private String name;
public NewLife(int age,String name) {
this.age=age;
this.name=name;
}
public boolean equals(Object obj){
if(this==obj) {
return true;
}
else if(obj instanceof NewLife)
{
// Object obj=new NewLife(); 此处涉及到了多态
NewLife nl=(NewLife)obj;
if(this.age==nl.age)
{
return true;
}
}
return false;
}
}
public class Test {
public static void main(String[] args) {
NewLife n1=new NewLife(12,"lihaiya");
NewLife n2=new NewLife(13,"dazhizhang");
boolean a=n1.equals(n2);
System.out.println(a);
}
}
我们能够注意到不论是我的重写,还是系统中的那个重写,都存在有强转这一操作原因如下:
我还是通过代码来说明对象等级的变化吧
NewLife n2=new NewLife(13,"dazhizhang");
1.这里的n2先是子类的一个对象
public boolean equals(Object obj)
2.obj就是我们传过去的n2,为什么要升高他的等级,我们倒也不想,但是我们重写的是父类中的方法,我们能改变的只是其内容,但是其所传参数的类型我们是绝对没有资格改的
所以这里n2从一个小小的子类对象变成了父类的对象 而且这里涉及到了多态下面就是隐藏的代码了
Object obj=new NewLife();
3.下面是强转的操作了
NewLife nl=(NewLife)obj;
为什么要强转,因为在我重写的方法中,我要比较的是子类中age是否相同,但是根据多态的性质,变量的查找是严格可着父类来的,如果子类中有父类中没有的话,系统是会报错的,所以这里我们必须把Object类型的obj转成子类NewLife类型才行。
另外还有一个判定是否需要强转的技巧,当我们不确定一个对象是否需要强转时,试着用变量名.的方式调用一下父类中没有,子类中存在的变量试试,报错的话,就要考虑一下等级问题了
六.总结
对于这个方法的理解最重要的还是自己能够重写出来一个equals方法。
因为在重写的过程中很多我们没有注意到或者不想去想的问题就会暴露出来。
equals方法相关总结的更多相关文章
- JAVA中复写equals方法
在JAVA中“==”用于比较两个引用对象的地址是否相同.但是如果我们想比较两个对象的内容是否相同,通常会覆写equals方法.equals方法用来比较两个对象的内容是否相等. package org. ...
- 深入解析字符串的比较方法:“==”操作符;String.Equals方法;String.Compare方法;String.CompareOrdinal方法。
1:要判断2个字符串变量是否相等,最高效的方法是看它们是否指向相同的内存地址.前面使用RefernceEquals方法来比较.如果2个变量指向的是不同的内存地址,那么就需要逐字符的比较2个字符串的变量 ...
- Effective Java 第三版——11. 重写equals方法时同时也要重写hashcode方法
Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将 ...
- K:java中的hashCode和equals方法
hashCode和equals方法是Object类的相关方法,而所有的类都是直接或间接的继承于Object类而存在的,为此,所有的类中都存在着hashCode和equals.通过翻看Object类 ...
- 为什么要重写hashcode和equals方法?初级程序员在面试中很少能说清楚。
我在面试 Java初级开发的时候,经常会问:你有没有重写过hashcode方法?不少候选人直接说没写过.我就想,或许真的没写过,于是就再通过一个问题确认:你在用HashMap的时候,键(Key)部分, ...
- C#基础知识之字符串比较方法:“==”操作符;RefernceEquals;String.Equals方法;String.Compare方法;String.CompareOrdinal方法。
一.“==”操作符:String.Equals:ReferenceEquals 方法 1.在编程中实际上我们只需要这两种比较,c#中类型也就这两种 (1)值类型的比较:一般我们就是判断两个值类型实例各 ...
- 重新编写equals()方法,hashCode()方法,以及toString(),提供自定义的相等标准,以及自描述方法
下面给出一个实例,重新编写equals()方法,提供自定义的相等标准 public class PersonTest { public static void main(String[] args) ...
- java中的equals方法
这个方法首先比较的是两个对象的地址是否相同,如果相同直接返回true, 否则, (1)如果是string类型的先比较是否是string类型,是的话,再比较是否长度相同,相同的话再比较,每个字符是否相同 ...
- 浅谈Java中的hashcode方法以及equals方法
哈希表这个数据结构想必大多数人都不陌生,而且在很多地方都会利用到hash表来提高查找效率.在Java的Object类中有一个方法: public native int hashCode(); 根据这个 ...
随机推荐
- Java基础12:深入理解Class类和Object类
更多内容请关注微信公众号[Java技术江湖] 这是一位阿里 Java 工程师的技术小站,作者黄小斜,专注 Java 相关技术:SSM.SpringBoot.MySQL.分布式.中间件.集群.Linux ...
- 【c#】RabbitMQ学习文档(一)Hello World
一.简介 RabbitMQ是一个消息的代理器,用于接收和发送消息,你可以这样想,他就是一个邮局,当您把需要寄送的邮件投递到邮筒之时,你可以确定的是邮递员先生肯定会把邮件发送到需要接收邮件的人的手里,不 ...
- 【bug】----- Git上传文件错误导致本地代码丢失
1.问题描述:通过Git上传本地文件,在git commit操作后本地未上传的代码全部丢失... 2.解决: 第一步:在项目目录下打开Git Bash: 第二步:输入 git reflog 第三步:在 ...
- java开发知识IO知识之输入输出流以及文件
目录 java开发知识IO知识之输入输出流以及文件 一丶流概述 二丶输入流讲解 InputStream类. 1. 输入流以及类层次结构 2.文件操作.使用输入流读取 三丶输出流 OutputStrea ...
- 浅析java程序的执行过程
在研究任何一门语言时,无论是面向过程的c,c++(面向过程和面向对象),还是面向对象的.net,java等,弄清语言执行过程至关重要. 何为语言执行过程? 所谓语言执行过程,指对于任何一门语言,如j ...
- Perl IO:IO重定向
文件句柄和文件描述符的关系 文件描述符是操作系统的资源,对于实体文件来说,每打开一次文件,操作系统都会为该进程分配一个文件描述符来关联(指向)这个文件,以后操作文件数据都根据这个文件描述符来操作,而不 ...
- 【Linux】Rsync的剖析与使用
目录 Rsync的工具剖析与使用 0.Rsync的介绍 1.Rsync的特性 2.Rsync的部署安装 3.搭建远程备份系统. Rsync的工具剖析与使用 0.Rsync的介绍 rsync是Linux ...
- VS 使用vs2017自带的诊断工具(Diagnostic Tools)诊断程序的内存问题
前言 一般来说.NET程序员是不用担心内存分配释放问题的,因为有垃圾收集器(GC)会自动帮你处理.但是GC只能收集那些不再使用的内存(根据对象是否被其它活动的对象所引用)来确定.所以如果代码编写不当的 ...
- 如何终止正在进行expdp导出数据的任务
不能用ctrl+c来终止导出 一.按照以前的习惯,在进行oracle数据库数据导出操作时,大家一般都会使用组合键“CTRL+C”来终止导出操作.但这种方法在expdp导出数据时,却不能使用,因为虽然可 ...
- Java开发笔记(六十五)集合:HashSet和TreeSet
对于相同类型的一组数据,虽然Java已经提供了数组加以表达,但是数组的结构实在太简单了,第一它无法直接添加新元素,第二它只能按照线性排列,故而数组用于基本的操作倒还凑合,若要用于复杂的处理就无法胜任了 ...