Java Collections – hashCode() 和 equals() – 如何在 Java 中覆盖 equals() 和 hashcode() 方法?

已发表: 2018-08-08
Java 集合 hashCode 和 equals

Java 中的equals()hashCode()是在 Object 类和部分或核心 Java 库中声明的两个基本方法。

如果您在 Java 中有以下任何问题,那么您来对地方了。

  • Java 实践 -> 实现 equals
  • override – 在 Java 中覆盖 equals 和 hashCode
  • 如何在java中覆盖equals()方法
  • 如何在java中覆盖hashCode()方法
  • 如何在 Java 中覆盖 equals 和 hashCode 方法
  • 如何以及为什么在 Java 中重写 equals 方法
  • 如果覆盖 equals(),为什么总是覆盖 hashcode()?

让我们看一个简单的例子来了解第一个Reference EqualityLogical Equality 。 相等运算符 (==) 将两个字符串的引用(内存中的地址)作为两个不同的数字进行比较——这称为Reference equality

Logical equality比较对象的数据而不是引用的值。

输出:

hashCodeequals密切相关:

  • 如果您覆盖equals ,则必须覆盖hashCode
  • hashCode必须为相等的对象生成相等的值。
  • equalshashCode必须依赖于same set of significant fields 。 您必须在这两种方法中使用相同的字段集。 您不需要使用所有字段。 例如,一个依赖于其他的计算字段很可能应该从equalshashCode中省略。

实现equals时,根据类型对字段进行不同的比较:

  • 对象字段,包括集合:使用equals
  • 类型安全枚举:使用equals== (在这种情况下,它们等同于相同的东西)
  • 可能为空的对象字段:同时使用==equals
  • 数组字段:使用Arrays.equals
  • floatdouble以外的原始字段:使用==
  • float : 转换为int使用Float.floatToIntBits ,然后使用==
  • double :使用Double.doubleToLongBits转换为long ,然后使用==

实现hashCode

  • 如果一个类覆盖了equals ,它必须覆盖hashCode
  • 当它们都被覆盖时, equalshashCode必须使用相同的字段集
  • 如果两个对象相等,那么它们的hashCode值也必须相等
  • 如果对象是不可变的,则hashCode是缓存和延迟初始化的候选对象

hashCode为对象提供唯一标识符是一种流行的误解。 它不是。

按照一般约定,Java 中的equals()方法必须是自反的、对称的、传递的、一致的,并且任何非空引用都必须返回 false。 换句话说,对于 a、b 和 c 的任意值,以下测试必须始终通过:

对于最佳实践,请使用以下步骤来实现您的 equals() 方法:

  • 使用 this == that 来检查引用相等
  • 使用instanceof测试正确的参数类型
  • 将参数转换为正确的类型
  • 比较重要字段是否相等

这是一个完整的例子。

CrunchifyImplementEqualsHashCode.java

Eclipse 控制台输出: