這其實是個老生常談的問題了,不過還是有人不理解,所以這裏就總結一下
一、介紹
我們知道任何對象都直接或者間接繼承Object類,而我們今天要探討的問題就定義在Object中,瞅一瞅
public boolean equals(Object obj) {
return (this == obj);
}
public native int hashCode();
可以看出來,equals方法在Object類中默認實現,其含義是比較兩個引用所指向的對象是否一樣(仔細理解一下)
而hashcode方法是native關鍵字修飾的,那麼它其實調用的是 定義在DLL庫(動態鏈接庫)中的實現。
google一下就知道hashcode在Object中的實現是利用內存地址獲得hashcode值
根據hashcode的註釋可以看到(看不到的自己看看源碼,太長這裏就不粘了)。
總的理念就兩條,
- equals方法相等,hashcode一定相等
- equals方法不等,hashcode不一定相等
二、品一品
從上面總結的定義可以看到,重寫equals方法必須要重寫hashcode方法其實是官方定義的,因爲當你重寫equals方法判斷兩個對象相等之後,不重寫hashcode的話hashcode就不一定相等了,這就違反了第一條規則。
但是經過試驗,其實重寫hashcode影響並不大,因爲當你顯示調用equals方法判斷兩個對象的時候就只涉及到equals方法的內容!和hashcode沒半毛錢關係(除非你在equals調用了hashcode )
所以重寫equals方法不一定要重寫hashcode方法?
但是你要明白,hashcode出現得有意義呀,不然爲什麼要有這個方法呢。
所以從設計的角度來看,重寫equals方法是必須要重寫hashcode方法,從而使它滿足上面兩條規則。(官方定義的,咱也沒辦法)
三、意義
那麼hashcode真正的意義在哪呢?
爲什麼一定要抱着equals方法一定要抱着hashcode一塊死?
emmmmmmm…
前面您也看到了,我說的是顯示調用equals方法!!!,當你調用別人的equals方法時,你保證別人不用hashcode方法???
看看最常用HashMap,瞭解一哈它的put方法流程
- 向HashMap添加元素的時候,需要先定位到在數組的位置(採用hashCode方法)。
- 如果只重寫了 equals 方法,兩個鍵的 equals 返回了true,集合是不允許出現重複鍵的,只能插入一個。
- 此時如果沒有重寫 hashCode 方法,那麼就無法定位到同一個位置,集合還是會插入鍵。這樣集合中就出現了重複鍵了。那麼重寫的equals方法就沒有意義了。所以一定要重寫!
貼個例子
import java.util.HashMap;
import java.util.Map;
public class HashTest {
private String name;
private String age;
public HashTest(String name, String age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
@Override
public boolean equals(Object obj) {
if(this.name==((HashTest)obj).name){
return true;
}
return false;
}
public static void main(String []args){
HashTest hashTest1=new HashTest("ming","12");
HashTest hashTest2=new HashTest("ming","12");
Map<HashTest,String> map=new HashMap<>();
map.put(hashTest1,"ming1");
map.put(hashTest2,"ming2");
//map長度爲2
}
}
可能有些小夥伴還反應不過來。解釋以下八…
這段邏輯代碼我們想實現的是map中以HashTest對象爲key,從代碼可以看出來,hashTest1和hashTest2應該是同一個對象,但是實際map中存儲時卻當作兩個不同的key來處理,想一想這段代碼是不是就與預期的實現不符!!!就是出現問題嘍!!!