为什么hashCode()和equals()都存在

为什么java Object类有两个方法hashcode()和equals()? 其中一个看起来多余,它渗透到最底层的派生类?

为什么你认为一个是多余的? 他们说不同的事情:

  • hashCode是“给我一些有效的方法来看两个对象是否可能相等”
  • equals是“检查这个对象是否真的等于另一个”

你肯定需要两者 – 虽然我不相信他们应该首先在Object中 。

您绝对需要哈希码以便使用哈希表执行高效查找 – 并且您绝对需要进一步的相等性检查,因为哈希发生冲突(例如,存在比哈希码更多的可能字符串)。

首先,当你重写equals()时,你必须覆盖hashcode()。

如果不这样做,将导致违反Object.hashCode的常规合同,这将阻止您的类与所有基于散列的集合(包括HashMap,HashSet和Hashtable)一起正常运行。

这是从Object规范[JavaSE6]复制的契约:

  • 每当在执行应用程序期间多次在同一对象上调用它时,hashCode方法必须始终返回相同的整数,前提是不修改对象的equals比较中使用的信息。 从应用程序的一次执行到同一应用程序的另一次执行,此整数不需要保持一致。
  • 如果两个对象根据equals(Object)方法相等,则在两个对象中的每一个上调用hashCode方法必须生成相同的整数结果。
  • 如果两个对象根据equals(Object)方法不相等则不是必需的,则对两个对象中的每一个调用hashCode方法必须产生不同的整数结果。 但是,程序员应该知道为不等对象生成不同的整数结果可能会提高哈希表的性能。

基本思想是通过比较hashcode()可以快速检查两个对象是否相等。 如果他们的哈希码相等,那么对象可能是相等的(不一定,但这是一个很好的猜测)。 然后执行使用equals()的更深刻(且更昂贵)的检查。 这对于加速所有类型的查找(来自地图等)非常重要。

equals是比较对象,hashcode用于从对象生成哈希值,然后由java地图容器(Hashtable,Map等)使用。

通常的做法是一起覆盖它们(如果覆盖哈希码,则需要覆盖等于,反之亦然)。