hashCode()与equals()方法的理解

来源:互联网 发布:妇女社会地位调查数据 编辑:程序博客网 时间:2024/06/07 11:38

面试题这问题,以前只是笼统的了解。现在深入的研究下。

首先两者的关系:

1、hashCode()相等的,equals()不一定相等;

2、hashCode()不相等,equals()一定不相等;

3、equals()相等,则hashCode()一定相等

4、equals()不相等,则hashCode()不能确定

两者之间的关系就像是字典的目录一样,同一个字开头的词语肯定存放在同一目录下,但是它们是两个词语,所以比较一下肯定不同的。所以hashCode()就是这里的字典目录的比较,而equals()则是除了比较目录位置之外,还比较两个词语的属性。

Object的hashCode()方法和equals()是用来比较两个对象是否相同的。一般比较时,会先调用hashCode()方法来计算出哈希值,根据对象的内存地址得到一个int类型的数,通过int的比较能够高效率的根据内存地址辨别两个对象是否相同(单从内存地址层面比较)。只有当哈希值比较相同时,然后通过equals()比较,我们去翻看Object源码时可以发现

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

object中的equals方法采用的==号比较,也就是还是默认的比较两个对象的内存地址,但是到了比如String类中时,JDK中默认的复写了equals方法,变成了对于String类型字符串内容的比较。

总结一下就是
基本数据类型(也称原始数据类型) :byte,short,char,int,long,float,double,boolean。他们之间的比较,应用双等号(==),比较的是他们的值
但是对于复合数据类型(类):当他们用(==)进行比较的时候,比较的是他们在内存中的存放地址(确切的说,是堆内存地址)。

所以对于类的比较就不能单一地使用==来比较类对象是否相同。因而当我们自己创建一个类对象,举个简单例子比如:

学生对象有两个属性 id,name,当我创建两个学生对象,但是给他们赋予相同的id,name。在我们理解是因为两个学生的编号和名字是一样的,我们认为两个学生是同一个人。但是在内存中,因为创建了两次,所以在内存中两个对象有自己的地址,所以此时来判别两个对象是否相同时,如果调用父类Object的hashCode()方法时,因为地址不同所以程序自动判定两个编号和名称相同的学生不是同一个学生。这与我们的判断不同,所以当我们的类进行比较时,必须要自己复写父类的hashCode()方法以及equals()方法。所以比如我们用到HashSet时,往里面存放的类对象,HashSet都会默认调用这两个方法,若不复写这两个方法,即使放入的对象属性完全相同,但是内存地址不同都能存放进set集合中,这样就失去了hashSet存放不同对象的特性。

0 0
原创粉丝点击