天天看点

hashCode()和equals()

hashCode()和equals()是什么?

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

hashCode()和equals()的区别

我们从两个角度介绍他们的区别:1. 性能,2. 可靠性,他们之间的主要区别也基本体现在这里。

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

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

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

  因为hashCode()并不是完全可靠,有时候不同的对象也们生成的hashCode也会一样(成生hash值的公式可能存在的问题),所以hashCode()只能说是大部分时候可靠,并不是绝对可靠,所以我们可以得出:

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

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

  1. 对于需要大量并且快速的对比的话,如果都用equals()去做显然效率太低,所以解决方式是,每当需要对比的时候,首先用hashCode()去对比,如果hashCode()不一样,则表示这两个对象肯定不相等(也就是不必再用equals()去再对比了),如果hashCode()相同,此时再对比他们的equals(),如果equals()也相同,则表示这两个对象是真的相同了,这样既能大大提高了效率,也保证了对比的绝对正确性。
  2. 这种大量的并且快速的对象对比一般使用的hash容器中,比如HashSet, HashMap等等,比如HashSet里要求对象不能重复,则他内部必然要对添加进去的每个对象进行对比,而他的对比规则就是像上面所说的那样,先hashCode(),如果hashCode()相同,再用equals()验证,如果hashCode()都不同,则肯定不同,这样对比的效率就很高了。
  3. 然而hashCode()和equals()一样都是基本类Object里的方法,而和equals()一样,Object里hashCode()里面只是返回当前对象的地址,如果是这样的话,那么我们相同的一个类,new两个对象,由于他们在内存里的地址不同,则他们的hashCode()不同,所以这显然不是我们想要的,所以我们必须重写我们类的hashCode()方法,即一个类,在hashCode()里面返回唯一的一个hash值,如果下面:
class Person{
   int num;
   String name;

   public int hashCode(){
       return num * name.hashCode() 
   }    
}      

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

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

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