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

##为什么要重写hashCode和equals方法?

1. 为什么要重写HashCodeequals方法?

当使用使用HashMap存入数据的键:key为自定义类时,需要重写;若不重写自定义类的HashCodeequals方法,所得结果与预期会不同。

2. 不重写HashCode会有什么后果?

首先需要强调一点,Object类的固有方法是根据两个对象的内存地址来判断,我对Object不甚了解,这里暂时先记着。

不重写HashCode,则存入自定义类时计算其hash值用的是默认的Object类的HashCode方法,该方法返回的hash值是传入自定义类对象的地址

若以自定义类的对象作Key的话,以值(id=1)为1的对象k1作键先存入一条数据value="001",再以值为id=1的对象k2来取出数据,得到的是null,因为HashMap中存的是,而传入的却是k2的地址,k1k2的地址明显是不同的,所以会返回null

3. 重写了HashCode不重写equals方法会有什么后果?

这里再次注明一点,由于hash存在冲突,所以HashMap采用链地址法来处理冲突,对应同一hash值的键将组成一个链表。

即不同的值可能对应同一hash值。

equals方法就是用来判断传入数据是否真的是要找的数据的。

所以如果重写了HashCode却没有重写equals方法,会出现即使根据hash查找这一步没出错,但在执行equals方法时却会因为k2k1的地址不同而返回null

4. HashCodeequals方法都重写了,那这时的HashMapget流程是怎样的?

创建自定义类的对象k1k2id属性都设为1。创建一个HashMap实例hm。执行:

hm.put(k1, "Key with id is 1");

然后执行:

System.out.println(hm.get(k2));

get的流程为:

1.因为重写了HashCode方法,所以现在是根据k2id=1来计算hash

2.因为k1id=1k2id=1相等,所以根据HashCode方法计算出来的hash会找到k1,此时还不能判断相等;

3.调用equals方法来判断,这里只要是两个对象(k1k2)的类型都为Keyid相等,就判断相等,这里k1k2都相等,且id都为1,故判断get成功,返回结果。

Key的定义

class Key {
    private Integer id;

    public Integer getId() {
        return id;
    }

    public Key (Integer id) {
        this.id = id;
    }

    public boolean equals(Object o) {
        if (o == null || !(o instanceof Key)) {
            return false;
        }else {
            return this.getId().equals(((Key) o).getId());
        }
    }

    public int hashCode() {
        return id.hashCode();
    }

}

个人理解,难免有不当之处,还望指正

你可能感兴趣的:(Java)