重写 hashcode真有那么简单嘛?

【重写 hashcode真有那么简单嘛?】万万没想到一个 hashcode() 方法 , 既然会引出一堆的知识盲区 , 简直了 。
起因:

老八股:为什么重写Equals方法要重写HashCode方法 。
大声告诉我为什么 , 闭着眼睛先把答案背出来 , 啥?这都忘了?没事 , 也不是啥大事 。这两句话再Object类的 hashcode 中的注释上就有 , 但是一般八股文不会告诉你是出自这里的 。凝聚成两句话就是:
1 如果两个对象通过equals()方法比较相等 , 那么这两个对象的hashCode一定相同 。
2 如果两个对象hashCode相同 , 不能证明两个对象是同一个对象(不一定相等) , 只能证明两个对象在散列结构中存储在同一个地址(不同对象hashCode相同的情况称为hash冲突) 。
  • 标准嘛 , 很标准 , 但是还不够 , 一般人到这里已经结束了 , 但是我还想和面试官在掰扯一下:从Object类中 hashcode 的注释上就写着很明白了 , 具体如下
/*** Returns a hash code value for the object. This method is* supported for the benefit of hash tables such as those provided by* {@link java.util.HashMap}.* <p>* The general contract of {@code hashCode} is:* <ul>* <li>Whenever it is invoked on the same object more than once during*an execution of a Java application, the {@code hashCode} method*must consistently return the same integer, provided no information*used in {@code equals} comparisons on the object is modified.*This integer need not remain consistent from one execution of an*application to another execution of the same application.* <li>If two objects are equal according to the {@code equals(Object)}*method, then calling the {@code hashCode} method on each of*the two objects must produce the same integer result.* <li>It is <em>not</em> required that if two objects are unequal*according to the {@link java.lang.Object#equals(java.lang.Object)}*method, then calling the {@code hashCode} method on each of the*two objects must produce distinct integer results.However, the*programmer should be aware that producing distinct integer results*for unequal objects may improve the performance of hash tables.* </ul>* <p>* As much as is reasonably practical, the hashCode method defined by* class {@code Object} does return distinct integers for distinct* objects. (This is typically implemented by converting the internal* address of the object into an integer, but this implementation* technique is not required by the* Java&trade; programming language.)** @returna hash code value for this object.* @seejava.lang.Object#equals(java.lang.Object)* @seejava.lang.System#identityHashCode*/public native int hashCode();
  • 看着很长 , 其实不然 , 给你们翻译一下第一句话---什么叫中式翻译 , 如下
Returns a hash code value for the object. This method is supported for the benefit of hash tables such as those provided by
返回 一个 hash code 值 为 这个 对象 。这个 方法 是 支持 的 这个 好处 体现为 hash 表 比如 这些 提供的 {@link java.util.HashMap}.
权威解释什么乱七八糟的 , 还是来看看比较权威的 。
  • Effective Java 第三版 中 描述为什么重写equals 方法后必须重写hashCode 方法
每个覆盖了equals方法的类中 , 必须覆盖hashCode 。如果不这么做 , 就违背了hashCode的通用约定 , 也就是上面注释中所说的 。进而导致该类无法结合所以与散列的集合一起正常运作 , 这里指的是HashMap、HashSet、HashTable、ConcurrentHashMap 。
提炼:如果重写equals不重写hashCode它与散列集合无法正常工作 。

经验总结扩展阅读