Object類是java的萬類之父,其中,equals和hashcode是Object類的2個非常重要的方法。
1. equals方法:
Object類中默認的實現(xiàn)方式是 :
public boolean equals(Object obj) return this == obj
也就是說,只有this 和 obj引用同一個對象,才會返回true。而我們往往需要用equals來判斷 2個對象是否等價,而非驗證他們的唯一性。這樣我們在實現(xiàn)自己的類時,就要重寫equals。
那么,按照約定,equals方法要滿足以下規(guī)則:
- 自反性: x.equals(x) 一定是true;
- 對null: x.equals(null) 一定是false;
- 對稱性: x.equals(y) 和 y.equals(x)結(jié)果一致;
- 傳遞性: a 和 b equals , b 和 c equals,那么 a 和 c也一定equals;
- 一致性: 在某個運行時期間,2個對象的狀態(tài)的改變不會不影響equals的決策結(jié)果,那么,在這個運行時期間,無論調(diào)用多少次equals,都返回相同的結(jié)果。
到此,常見的面試問題就不是問題了。
問:equals相等,兩個類一定相等嗎?
答曰:默認情況下,equals相等,兩個類一定相等;如果重寫的話,那就不一定嘍。
equals重寫的正確姿勢:
public boolean equals(Object obj)
{
if (this == obj)
return true;
if ((obj == null) || (obj.getClass() != this.getClass()))
return false;
//能執(zhí)行到這里,說明obj和this同類且非null。
Test test = (Test) obj;
return num == test.num&& (data == test.data || (data != null && data.equals(test.data)));
}
equals重寫的應該避免的姿勢:
if((obj == null) || (obj.getClass() != this.getClass()))
return false;
if(!(obj instanceof Test))
return false; // avoid 避免!
避免!僅當沒有子類時正確
注:equals方法的參數(shù)類型是Object
2. hashcode方法:
這個方法返回對象的散列碼,返回值是int類型的散列碼。
(HashCode的存在主要是用于查找的快捷性,如Hashtable,HashMap等,HashCode是用來在散列存儲結(jié)構(gòu)中確定對象的存儲地址的)。如果沒有hashcode,那么就需要調(diào)用equals方法進行對比,equals方法實現(xiàn)一般比較麻煩。如果有hashcode,我們可以先根據(jù)hashcode方法進行判斷,如果相等,再用equals方法對比。
關(guān)于hashCode方法,一致的約定是:
- 重寫了euqls方法的對象必須同時重寫hashCode()方法。
- 如果2個對象通過equals調(diào)用后返回是true,那么這個2個對象的hashCode方法也必須返回同樣的int型散列碼。
- 如果2個對象通過equals返回false,他們的hashCode返回的值允許相同。(然而,程序員必須意識到,hashCode返回獨一無二的散列碼,會讓存儲這個對象的hashtables更好地工作)
總結(jié)一句話:等價的(調(diào)用equals返回true)對象必須產(chǎn)生相同的散列碼。不等價的對象,不要求產(chǎn)生的散列碼不相同。