天天看点

重写equal()为什么需要重写hashCode方法

重写equal()为什么需要重写hashCode方法,很多地方都提过这段话,那么为什么要这么做呢?

下面我举个HashMap 的插入/取出的例子为大家讲解

需要注意:

在HashMap 的存取是根据hashCode的值存放与取出的。如果需要以自定义类的内容来作为Map的key的话,那就得小心了。

一个小demo

//测试代码
    @Test
    public void MapTest(){
        Map<User,String> map=new HashMap<User,String>();    
        //只重写了equal的自定义实体类
        User InsertUser=new User(, "hello");
        System.out.println("插入时的key"+InsertUser);
        System.out.println("key的hashCode--"+InsertUser.hashCode());
        map.put(InsertUser,"InsertData");

        User getUser=new User(,"hello");       
        System.out.println("取出时的key"+getUser);
        System.out.println("key的hashCode--"+getUser.hashCode());
        System.out.println("对应的value--"+map.get(getUser));  
    }
           

实体类

package map;
//只重写了equal方法
public class User {
    private int id; 
    private String name;
    public User(int id, String name) {
        super();
        this.id = id;
        this.name = name;
    }
    @Override
    public boolean equals(Object obj) {
        User u=(User)obj;
        if(u.id == this.id  && u.name==name)
            return true;
        else 
            return false;
    }
    @Override
    public String toString() {
        return "User [id=" + id + ", name=" + name + "]";
    }
}
           

结果

插入时的keyUser [id=, name=hello]
取出时的keyUser [id=, name=hello]
对应的value--null
           

显然,表面上看上去我们放进去的和取出的key一样(自定义的equal规则),但是二者hashCode不同,当然取不到值,这也验证了我们上面所说,HashMap 的取出时根据HashCode值来的。

于是咱们重写hashCode试试

package map;
//重写了equal和hashCode方法
public class User {
    private int id; 
    private String name;
    public User(int id, String name) {
        super();
        this.id = id;
        this.name = name;
    }
    @Override
    public boolean equals(Object obj) {
        User u=(User)obj;
        if(u.id == this.id  && u.name==name)
            return true;
        else 
            return false;
    }
    @Override
    public String toString() {
        return "User [id=" + id + ", name=" + name + "]";
    }

    @Override
    public int hashCode() {
        return this.id;
    }
}
           

结果

插入时的keyUser [id=, name=hello]
key的hashCode--1
取出时的keyUser [id=, name=hello]
key的hashCode--1
对应的value--InsertData
           

bingo

小结

自定义equal规则时要一并重写hashCode方法。

继续阅读