重写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(1, "hello");
System.out.println("插入时的key"+InsertUser);
System.out.println("key的hashCode--"+InsertUser.hashCode());
map.put(InsertUser,"InsertData");
User getUser=new User(1,"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=1, name=hello]
取出时的keyUser [id=1, 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=1, name=hello]
key的hashCode--1
取出时的keyUser [id=1, name=hello]
key的hashCode--1
对应的value--InsertData
bingo
小结
自定义equal规则时要一并重写hashCode方法。