java为什么重写equals的时候要重写hashcode.md

jasmine 于 2019-01-19 发布

探索为什么重写equals方法

因为要比较两个对象是否相等

Object中比较两个对象相等是怎样比较的呢?

//Object中equals源码
public boolean equals(Object obj) {
    return (this == obj);
}

从中发现,是比较的地址值。

当重写equals,不重写hashcode

当我们比较两个对象的时候,如果单纯用equals方法比较的话,是相等的,但不代表地址值一定相同。

比如:

在对象初始化new的时候会分配两个不同的地址值,这样的话虽然内容相同,但是是两个地址值不同的对象。 这样在HashMap中的时候,是在不同的hash桶中的。你在put和get的时候是先计算你的hashcode,然后再去调用equals的。

我让hashCode()每次都返回一个固定的数行吗

@Override
public int hashCode() {
    return 10;
}

如果这样的话,HashMap, HashSet等集合类就失去了其 “哈希的意义”.用中的话来说就是,哈希表退化成了链表.如果hashCode()每次都返回相同的数,那么所有的对象都会被放到同一个bucket中,每次执行查找操作都会遍历链表,这样就完全失去了哈希的作用.

场景

重写示例(idea有快捷键)

@Getter
@Setter
@NoArgsConstructor
public class Student {
    /**
     * 姓名
     */
    private String name;

    /**
     * 年龄
     */
    private Integer age;
    
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Student student = (Student) o;
        return name.equals(student.name) && age.equals(student.age);
    }

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