为什么重写equals方法必须重写hashcode方法

在Java中,重写equals()方法的同时也应该重写hashCode()方法,这是因为这两个方法在 Java 中是有关联的,而且它们一起影响着集合类的行为。

Java中的hashCode()方法用于返回对象的哈希码,而equals()方法用于比较两个对象是否相等。在集合类(如HashMap、HashSet等)中,hashCode()方法被用来确定对象在内部存储结构中的位置,以便更快地进行查找。如果两个对象在equals()方法中被认为相等,那么它们的hashCode()方法应该返回相同的值。

下面是一些原因说明为什么重写hashCode()方法是很重要的:

集合类的性能: 在使用哈希集合(如HashMap、HashSet)时,对象的hashCode()方法影响着集合的性能。如果两个相等的对象返回不同的哈希码,它们可能会被放置在不同的存储桶中,导致集合无法正确工作。

保持一致性: 根据equals()方法的规范,如果两个对象相等,它们的哈希码应该相等。这是为了确保当一个对象被修改后,它在集合中的位置不会改变,从而保持集合的一致性。

符合对象相等性原则: 如果两个对象通过equals()方法比较相等,那么它们的哈希码应该相等。这是为了保持Java对象相等性原则的一致性。

为了满足这些要求,当你重写了equals()方法时,最好也一并重写hashCode()方法。

当你只重写了equals()方法而没有重写hashCode()方法时,可能导致相等的对象拥有不同的哈希码,这会违反哈希表的基本性质。下面是一个例子:

import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

class Person {
    private String name;
    private int age;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Person person = (Person) o;
        return age == person.age && Objects.equals(name, person.name);
    }

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

public class myTest {
    public static void main(String[] args) {
        Map<Person, String> personMap = new HashMap<>();

        Person person1 = new Person("John", 25);
        Person person2 = new Person("John", 25);
        
        System.out.println(person1 == person2);   // new出来的两个对象,内存地址肯定不一样,所以返回false
        System.out.println(person1.equals(person2));  // true  return age == person.age && Objects.equals(name, person.name);

        personMap.put(person1, "Person 1");  // 向map集合中添加数据

        // 尽管 person2 与 person1 equals() 返回 true,但由于没有重写 hashCode(),它们的哈希码不同
        // 取值
        System.out.println(personMap.get(person2)); // 输出 null
        System.out.println(personMap.get(person1));  // 输出 Person 1
    }
}

结果1:
没有重写hashcode()方法
为什么重写equals方法必须重写hashcode方法_第1张图片
personMap.get(person2)时,返回的结果为null。这违反了哈希表的期望行为,即相等的对象应该有相等的哈希码。

结果2:
同时重写equals() 和 hashcode() 方法
为什么重写equals方法必须重写hashcode方法_第2张图片
此时用personMap.get(person2)取值时,结果返回Person 1
这确保了相等的对象具有相等的哈希码。在实际应用中,你可能需要根据具体的对象属性选择更适合的生成哈希码的方式。

你可能感兴趣的:(java面试题,java)