HashCode与equals不得不说的那些事

咱们常常能够看到这个问题,为何重写equals方法时,也必须重写HashCode()方法呢?咱们来一探究竟!
当有一个疑问的时候,咱们不只须要解开疑惑,更须要了解为何会有这个问题?它从哪里来?要去哪里?为何?这样都搞明白,这个问题不只解决了,并且留下了很深入的印象。
先聊一聊HashCode是干吗的?equals又是干吗的?二者有什么关系致使一方重写另外一方也须要重写呢?java

为何要有HashCode:
这里以HashSet如何检查重复来描述HashCode:web

  • 把对象加入HashSet时,HashSet会先计算对象的HashCode值来计算对象加入的位置,同时也会与该位置其余已经加入的对象作比较。若是HashCode值不一样,那么会假设对象没有重复出现。可是若是HashCode值相同,就会调用equals方法来检查HashCode值相同的对象是否真的相同。若是二者都相同,就不会让其加入成功。若是不一样,就会从新散列到其余位置。这样就减小了equals次数,提升了执行速度。

HashCode的做用:数据结构

  • equals同样,HashCode属于Object.java,因此全部类都包含HashCode方法。
  • HashCode的做用是获取哈希码,也称散列码。它实际上返回的是一个int整数。这个哈希码的做用是肯定该对象在哈希表中位置
  • 散列表的存储方式为Key-Value,可以根据键快速找到值(快速找到对象)
  • HashCode值在散列表中才会发挥其效果,在其余状况下无用。在散列表中,HashCode()方法是获取对象的哈希值,从而肯定对象在散列表中的位置。

HashCode与equals:
上面说到,hashCode值在非散列表中不起任何做用,因此二者关系分如下两种状况:svg

  • 不会建立类的对应散列表
    • 就是说不会再本质是散列表的数据结构中用到该类,好比hashSet, hash Table, HashMap,这种状况下,二者没有任何关系。equals用来比较两个对象是否相等,hashCode不会起到任何做用;
  • 会建立类的队友散列表,那么二者是有关系的
    • 若是两个对象相等,那么他们的hashCode值必定相同
    • 两个对象相同,分别调用equals()方法都返回true
    • 两个对象有相同的 hash code 值,它们也不必定是相等的
    • 所以,equals 方法被覆盖过,则 hashCode 方法也必须被覆盖
    • hashCode() 的默认行为是对堆上的对象产生独特值。若是没有重写 hashCode(),则该 class 的两个对象不管如何都不会相等(即便这两个对象指向相同的数据)