返回

重写 equals 方法时重写 hashCode 方法的重要性

前端

为什么重写 equals 方法时要重写 hashCode 方法?

在 Java 中,当两个对象的 equals 方法返回 true 时,表示这两个对象是相等的。而 hashCode 方法返回一个整数,用于唯一地标识对象。当对象存储在散列表中时,如 HashMap 和 HashSet,hashCode 方法被用来确定将对象存储在哪个桶中。

如果两个对象相等(即 equals 方法返回 true),那么它们的 hashCode 方法也应该返回相同的值。否则,散列表将无法正确地存储和检索对象。

举个例子,假设我们有一个 Person 类,它包含 name 和 age 两个属性。我们重写了 equals 方法,使其比较 name 和 age 属性,如果两个对象的 name 和 age 都相等,则返回 true,否则返回 false。

public class Person {
    private String name;
    private int age;

    public boolean equals(Object o) {
        if (o == this) {
            return true;
        }

        if (!(o instanceof Person)) {
            return false;
        }

        Person other = (Person) o;

        return this.name.equals(other.name) && this.age == other.age;
    }

    public int hashCode() {
        return name.hashCode() + age;
    }
}

如果我们只重写了 equals 方法,没有重写 hashCode 方法,那么当我们把两个具有相同 name 和 age 的 Person 对象添加到 HashMap 中时,HashMap 将无法正确地存储和检索这些对象。因为这两个对象的 hashCode 方法返回不同的值,因此它们会被存储在不同的桶中。

如何正确地重写 equals 和 hashCode 方法?

为了确保代码的正确性和性能,在重写 equals 方法时,需要遵循以下原则:

  • 只有当两个对象在语义上相等时,才让 equals 方法返回 true。
  • 只有当两个对象的 hashCode 方法返回相同的值时,才让 equals 方法返回 true。
  • 如果两个对象的 equals 方法返回 true,那么它们的 hashCode 方法也应该返回相同的值。
  • 对于任何给定的对象,hashCode 方法应该始终返回相同的值。
  • hashCode 方法应该在合理的时间内返回结果。

通常情况下,我们可以通过以下步骤来重写 equals 和 hashCode 方法:

  1. 定义一个包含所有要比较的属性的字段集合。
  2. 在 equals 方法中,比较这些字段,如果所有字段都相等,则返回 true,否则返回 false。
  3. 在 hashCode 方法中,将这些字段的值组合成一个整数,并返回该整数。

例如,对于 Person 类,我们可以这样重写 equals 和 hashCode 方法:

public class Person {
    private String name;
    private int age;

    public boolean equals(Object o) {
        if (o == this) {
            return true;
        }

        if (!(o instanceof Person)) {
            return false;
        }

        Person other = (Person) o;

        return this.name.equals(other.name) && this.age == other.age;
    }

    public int hashCode() {
        return Objects.hash(name, age);
    }
}

通过遵循这些原则和步骤,我们可以确保在重写 equals 和 hashCode 方法时,代码的正确性和性能。