大纲
本文会介绍一下==和equals的区别,以及相关的一些知识点。
基本区别
首先,对于基本数据类型,= =和equals是没有任何区别的;
对于引用数据类型,比如String,==比较的是二者的引用地址,而equals比较的是二者的值,具体举个例子:
有一个字符串A,值为“你好”,而A在内存中的地址是@sdfses345234;另外一个字符串B的值也是“你好”,但是在内存中的地址是@sfsafa323,此时使用==对A和B进行比较,结果为false,如果使用equals比较,结果为true
注:Object类的==和equals()方法也是没有区别的。
hash、hashCode和hashCode()
区分一下这几个概念。
1.hash函数是一类函数的统称,我们有很多种hash算法,它们都会生成一个hash表;
2.使用hash函数生成hash表,hashCode就是某一个元素在hash表中的位置;注意,hashCode不是对象在内存的地址,而是经过hash函数后在hash表中的位置;
3.hashCode()方法是Object的一个方法,所以说所有对象都是有hashCode()方法的,这个方法使用的是一种特殊的算法,计算hashCode,所以说hashCode()算是一种特殊的hash函数。
hashCode()和equals()的关系
如果两个值相同,那么hashCode一定相同;
如果两个值的hashCode相同,这两个值不一定相同,只是可能性比较大;
利用这两个特性,equals()方法在判断两个值是否相等之前,会先判断两个值的hashCode是否相等,如果相等,再判断值是否相等,如果hashCode不相同,直接返回false;
为什么要多此一举呢,因为很多时候两个对象会比较大,直接进行比较效率会比较慢,而获取对象的hashCode很快,比较两个hashCode也很快,我们可以通过这种方法提高equals方法的效率。
重写equals()方法为什么要重写hashCode()?
这个问题解释起来比较麻烦,我还是举例说明:
Public class Student {
String name;
String address;
int age;
Student(String name, String address, int age) {
this.name = name;
this.address = address;
this.age = age;
}
对于这个类,我们new两个对象
studentA = new Student(“张三”, “三合屯监狱”, 18)
studentB = new Student(“张三”, “三合屯监狱”, 18)
重写equals方法,来判断两个对象的元素值是否相等,经过测试,没有问题,studentA.equals(studentB)返回true。
但是如果我们将这两个对象put到HashSet中去的时候,我们会发现,这两个都放进去了,并不会覆盖,为什么会这样呢?
原因也很简单,因为hashSet在判断两个对象是否相同之前,会先判断两个对象的hashCode是否相同,对于一个自定义的类,new两个一模一样的对象,如果不重写hashCode(),这两个对象的hashCode就是根据这两个对象的内存地址计算得来的,基本上肯定是不相同的,就会造成判断出错,这显然不是我们想要的。所以,对于自定义类,如果要重写equals方法,就必须重写hashCode方法。