重寫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方法。