Javaequal 和 hashcode使用

Posted Jomini

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Javaequal 和 hashcode使用相关的知识,希望对你有一定的参考价值。

 

一、hashCode()和equals()是什么?

  hashCode()方法和equals()方法的作用其实一样,在Java里都是用来对比两个对象是否相等一致。

Equal

  没有重写的equal 使用是继承自 Object 的 equal 方法,和 “==” 的作用一样, 比较两个对象的内存地址是否相等。

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

  重写过的 equal, 比较的是两个对象的属性变量值 是否相等。

HashCode

  hashCode是对象在内存地址通过hash算法得到的哈希码。

 

二、hashCode()和equals()的区别

下边从两个角度介绍了他们的区别:一个是性能,一个是可靠性。他们之间的主要区别也基本体现在这里。

1、equals()既然已经能实现对比的功能了,为什么还要hashCode()呢?

因为重写的equals()里一般比较的比较全面比较复杂,这样效率就比较低,而利用hashCode()进行对比,则只要生成一个hash值进行比较就可以了,效率很高。

2、hashCode()既然效率这么高为什么还要equals()呢?

因为hashCode()并不是完全可靠,有时候不同的对象他们生成的hashcode也会一样(生成hash值得公式可能存在的问题),所以hashCode()只能说是大部分时候可靠,并不是绝对可靠,所以我们可以得出(PS:以下两条结论是重点,很多人面试的时候都说不出来):

  • equals()相等的两个对象他们的hashCode()肯定相等,也就是用equals()对比是绝对可靠的。

  • hashCode()相等的两个对象他们的equals()不一定相等,也就是hashCode()不是绝对可靠的。

 

三、hashCode()和equals()使用的注意事项

  1、对于需要大量并且快速的对比的话如果都用equals()去做显然效率太低,所以解决方式是,每当需要对比的时候,首先用hashCode()去对比,如果hashCode()不一样,则表示这两个对象肯定不相等(也就是不必再用equals()去再对比

了),如果hashCode()相同,此时再对比他们的equals(),如果equals()也相同,则表示这两个对象是真的相同了,这样既能大大提高了效率也保证了对比的绝对正确性!

      

 

 

  2、这种大量的并且快速的对象对比一般使用的hash容器中,比如HashSet,HashMap,HashTable等等,比如HashSet里要求对象不能重复,则他内部必然要对添加进去的每个对象进行对比,而他的对比规则就是像上面说的那样,先hashCode(),如果hashCode()相同,再用equals()验证,如果hashCode()都不同,则肯定不同,这样对比的效率就很高了。

  3、然而hashCode()和equals()一样都是基本类Object里的方法,而和equals()一样,Object里hashCode()里面只是返回当前对象的地址,如果是这样的话,那么我们相同的一个类,new两个对象,由于他们在内存里的地址不同,则他们的

hashCode()不同,所以这显然不是我们想要的,所以我们必须重写我们类的hashCode()方法,即一个类,在hashCode()里面返回唯一的一个hash值,比如下面:

 

  由于标识这个类的是他的内部的变量num和name,所以我们就根据他们返回一个hash值,作为这个类的唯一hash值。

所以如果我们的对象要想放进hashSet,并且发挥hashSet的特性(即不包含一样的对象),则我们就要重写我们类的hashCode()和equals()方法了。像String,Integer等这种类内部都已经重写了这两个方法。

当然如果我们只是平时想对比两个对象 是否一致,则只重写一个equals(),然后利用equals()去对比也行的  

 

4、什么时候需要重写?

  一般的地方不需要重载hashCode,只有当类需要放在HashTable、HashMap、HashSet等等hash结构的集合时才会重载hashCode。

 

5、那么为什么要重载hashCode呢?

  如果你重写了equals,比如说是基于对象的内容实现的,而保留hashCode的实现不变,那么很可能某两个对象明明是“相等”,而hashCode却不一样。

  这样,当你用其中的一个作为键保存到hashMap、hasoTable或hashSet中,再以“相等的”找另一个作为键值去查找他们的时候,则根本找不到。

 

6、为什么equals()相等,hashCode就一定要相等,而hashCode相等,却不要求equals相等?

  • 因为是按照hashCode来访问小内存块,所以hashCode必须相等。

  • HashMap获取一个对象是比较key的hashCode相等和equals为true。

  之所以hashCode相等,却可以equal不等,就比如ObjectA和ObjectB他们都有属性name,那么hashCode都以name计算,所以hashCode一样,但是两个对象属于不同类型,所以equals为false。

 

7、为什么需要hashCode?

  • 通过hashCode可以很快的查到小内存块。

  • 通过hashCode比较比equals方法快,当get时先比较hashCode,如果hashCode不同,直接返回false。

 

------------------------------------------

https://blog.csdn.net/xlgen157387/article/details/88087963

以上是关于Javaequal 和 hashcode使用的主要内容,如果未能解决你的问题,请参考以下文章

在TreeSet和TreeMap中使用hashCode()和equals()

代码安全 | 第十七期:对象只定义了Equals和Hashcode方法之一的漏洞

java 17 - 4 HashCode()保证元素唯一性的代码体现以及图解

Array [Byte] hashCode()每次在Scala中都返回不同的值

Java学习:identityHashCode和hashCode方法

Java的hashCode和equals方法