为什么要有 hashCode引用
我们以“HashSet 如何检查重复”为例子来说明为什么要有 hashCode:

当你把对象加入 HashSet 时,HashSet 会先计算对象的 hashcode 值来判断对象加入的位置,同时也会与其他已经加入的对象的 hashcode 值作比较,如果没有相符的hashcode,HashSet会假设对象没有重复出现。但是如果发现有相同 hashcode 值的对象,这时会调用 equals()方法来检查 hashcode 相等的对象是否真的相同。如果两者相同,HashSet 就不会让其加入操作成功。如果不同的话,就会重新散列到其他位置。这样我们就大大减少了 equals 的次数,相应就大大提高了执行速度。

SRE实战 互联网时代守护先锋,助力企业售后服务体系运筹帷幄!一键直达领取阿里云限量特价优惠。

hashCode()与equals()的相关规定
如果两个对象相等,则hashcode一定也是相同的
两个对象相等,对两个对象分别调用equals方法都返回true
两个对象有相同的hashcode值,它们也不一定是相等的
因此,equals 方法被覆盖过,则 hashCode 方法也必须被覆盖
hashCode() 的默认行为是对堆上的对象产生独特值。如果没有重写 hashCode(),则该 class 的两个对象无论如何都不会相等(即使这两个对象指向相同的数据)

所以,在向HashSet中存放自定义类型对象时,一定要重写hashCode和equals方法

package homework.day06;

import java.util.HashSet;

public class OverRideEquals {
    public static void main(String[] args) {
        EqualsTest test = new EqualsTest();
        Person person = new Person("mike","20");
        test.test();
        for(Person p:EqualsTest.set) {
            if (p.equals(person))
                System.out.println(p);
        }       
    }
}

class Person {
    private String name;
    private String age;
    
    Person(String name, String age) {
        this.name = name;
        this.age = age;
    }
    
    public void setName(String name) {
        this.name = name;
    }
    
    public String getAge() {
        return age;
    }
    
    public String getName() {
        return name;
    }
    
    @Override
    public String toString() {
        return "[" + name + "," + age + "]";
    }
    
    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj instanceof Person) {
            if (this.name.equals(((Person) obj).getName()) && this.age.equals(((Person) obj).getAge())) {
                return true;// 先判断类型是否相同,如果相同再判断属性是否都相同
            }
        }
        
        return false;   
    }
    
    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + Integer.valueOf(age);
        result = prime * result + ((name == null) ? 0 : name.hashCode());
        return result;// 如果姓名和年龄相等对应hashcode相等
    }
}


class EqualsTest {
    static HashSet<Person> set  = new HashSet<Person>();
    public void test() {
        set.add(new Person("mike", "20"));
        set.add(new Person("mike", "30"));
        set.add(new Person("mike", "30"));
        System.out.println(set);
    }

 }
扫码关注我们
微信号:SRE实战
拒绝背锅 运筹帷幄