hascode和equals为什么要同时复写—Java源码中的奥秘

在很多编程手册和技术推送文章中,都要求我们在创建一个类型的对象时候,强烈建议实现的其中的几个方法,一般包括:
  • 1.  toString()
  • 2. equals()
  • 3. hashcode()
 此外,在复写equals方法的时候要同时复写hashCode()方法是为什么呢?
首先我们来看一下两个方法在万物之王Object中的定位,与默认实现;
   
   
  1. /**
  2. * Returns a hash code value for the object. This method is
  3. * supported for the benefit of hash tables such as those provided by
  4. * {@link java.util.HashMap}.
  5. * The general contract of {@code hashCode} is:
  6. * Whenever it is invoked on the same object more than once during
  7. * an execution of a Java application, the {@code hashCode} method
  8. * must consistently return the same integer, provided no information
  9. * used in {@code equals} comparisons on the object is modified.
  10. * This integer need not remain consistent from one execution of an
  11. * application to another execution of the same application.
  12. * <li>If two objects are equal according to the {@code equals(Object)}
  13. * method, then calling the {@code hashCode} method on each of
  14. * the two objects must produce the same integer result.
  15. * <li>It is <em>not</em> required that if two objects are unequal
  16. * according to the {@link java.lang.Object#equals(java.lang.Object)}
  17. * method, then calling the {@code hashCode} method on each of the
  18. * two objects must produce distinct integer results. However, the
  19. * programmer should be aware that producing distinct integer results
  20. * for unequal objects may improve the performance of hash tables.
  21. * </ul>
  22. * <p>
  23. * As much as is reasonably practical, the hashCode method defined by
  24. * class {@code Object} does return distinct integers for distinct
  25. * objects. (This is typically implemented by converting the internal
  26. * address of the object into an integer, but this implementation
  27. * technique is not required by the
  28. * Java<font size="-2"><sup>TM</sup></font> programming language.)
  29. *
  30. * @return a hash code value for this object.
  31. * @see java.lang.Object#equals(java.lang.Object)
  32. * @see java.lang.System#identityHashCode
  33. */
  34. public native int hashCode();
  35. /**
  36. * Indicates whether some other object is "equal to" this one.
  37. * The {@code equals} method implements an equivalence relation
  38. * on non-null object references:
  39. * <ul>
  40. * <li>It is <i>reflexive</i>: for any non-null reference value
  41. * {@code x}, {@code x.equals(x)} should return
  42. * {@code true}.
  43. * <li>It is <i>symmetric</i>: for any non-null reference values
  44. * {@code x} and {@code y}, {@code x.equals(y)}
  45. * should return {@code true} if and only if
  46. * {@code y.equals(x)} returns {@code true}.
  47. * <li>It is <i>transitive</i>: for any non-null reference values
  48. * {@code x}, {@code y}, and {@code z}, if
  49. * {@code x.equals(y)} returns {@code true} and
  50. * {@code y.equals(z)} returns {@code true}, then
  51. * {@code x.equals(z)} should return {@code true}.
  52. * <li>It is <i>consistent</i>: for any non-null reference values
  53. * {@code x} and {@code y}, multiple invocations of
  54. * {@code x.equals(y)} consistently return {@code true}
  55. * or consistently return {@code false}, provided no
  56. * information used in {@code equals} comparisons on the
  57. * objects is modified.
  58. * <li>For any non-null reference value {@code x},
  59. * {@code x.equals(null)} should return {@code false}.
  60. * </ul>
  61. * <p>
  62. * The {@code equals} method for class {@code Object} implements
  63. * the most discriminating possible equivalence relation on objects;
  64. * that is, for any non-null reference values {@code x} and
  65. * {@code y}, this method returns {@code true} if and only
  66. * if {@code x} and {@code y} refer to the same object
  67. * ({@code x == y} has the value {@code true}).
  68. * <p>
  69. * Note that it is generally necessary to override the {@code hashCode}
  70. * method whenever this method is overridden, so as to maintain the
  71. * general contract for the {@code hashCode} method, which states
  72. * that equal objects must have equal hash codes.
  73. *
  74. * @param obj the reference object with which to compare.
  75. * @return {@code true} if this object is the same as the obj
  76. * argument; {@code false} otherwise.
  77. * @see #hashCode()
  78. * @see java.util.HashMap
  79. */
  80. public boolean equals(Object obj) {
  81. return (this == obj);
  82. }

    其实道理已经在上面标示彩色部分了 ,简单翻译一下: 在第12/70行的红字部分要求我们在复写equals方法的时候要复写hashCode方法,其原因是要保护两个方法之间的契约;这个 契约就是当两个对象equals的时候,其hashcode必然相等 。(在hash算法的数据结构中,两个相同的对象可以放到相同的位置,和被相同的keyObj索引找到)也就是说这两个方法彼此有个约定需要遵守,所以我们要按照约定同时复写这两个方法。同时注意到绿字部分, 当两个对象 hashcode相同 的时候,两者不必然相等,这个是由于hash算法决定的。我们应该尽力避免两个不同的对象生成相同的hashcode,也就是避免hash冲突,从而提高依赖hashCode的数据结构的读写性能

    如何科学的复写hashCode: 
  • 本类型中的成员属性都科学的复写了equals和hashCode
  • equals方法中使用了哪些变量进行比较,就在hashCode中使用那些变量去生成code。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值