關於重寫對象equals方法的問題
1.==和equals的區別
a.基本數據類型使用 == 進行值的比較
b.引用類型使用 == 進行比較時,直接比較的是對象的存儲地址,即兩個引用是否指向了同一個對象。
c.equals方法是基類Object中的方法,該方法如果在其他類中沒有被重寫,則比較的還是地址,即兩個引用是否指向了同一個對象,和==是一樣的(其實equals方法的默認實現就是==)。該方法在一些實現類中已經被重新了,如 String和Integer等包裝類,在這些類中用來比較值是否相等。
即:equals方法如果沒有重寫時在比較兩個對象時的作用和==是一樣的,都是比較兩個對象是不是同一個對象。這裏如果我們比較的是地址,那麽最好用==,因為無論是否重寫了Object的equals方法,引用類型使用==時永遠比較的是地址。
2.為什麽要重寫equals方法?
有時候在實際使用的過程中,比如有兩個對象 Address address1=new Address("甘肅”,"蘭州"); Address address2=new Address("甘肅”,"蘭州"); 這兩個對象中的內容都是相同的,我們則認為這兩個對象是相等的。但不重寫equals時使用 address1.equals(address2)進行比較時結果為 false,這不能滿足我們的要求,所以就需要對從基類Object中繼承的該方法進行重寫,以使其符合我們的要求。
3.應該如何重寫equals方法?
重寫equals方法時,除了最基本的要判斷兩個對象的類型是否相同,以及屬性值是否相同之外,有很重要的一點就是需要重寫其hashcode方法,因為java中規則約定:如果兩個對象equals後的結果為true時,他們的hashcode值一定是相同的;如果equals的結果為false時,則應盡量使他們的hashcode值不同。
這麽約定是為了避免在使用 HashMap,HashList等集合時出現沖突,因為在默認情況下每個對象的hashcode值是通過其內存地址經過計算得到的一個int型的值,所以每個對象的hashcode值是不同的。如果給HashMap中存入以下的鍵值對時:Map<Adress,String> map= new HashMap<Adress,String>(),即這裏使用引用類型來做map集合的鍵,map集合中的鍵是不能重復的,在往map集合中存入數據時,當前的鍵值會跟已經存入的鍵值進行比較,而比較的方法正是使用hashcode.如果不重寫hashcode,經我們重寫equals後兩個屬性值相同的對象我們認為就是相同的,但他們的hashcode還是不同的,所以這裏如果存入到map集合中時,map集合還認為他們依舊是兩個不同的對象,依舊能夠存入,這就不對了。所以一定要重寫hashcode值, 讓它符合java中的約定規則。這裏重寫的時候我們只需想辦法讓這個hashcode值能滿足上面所說的約定即可。註意,這裏的hashcode值的生成規則是我們根據自己的需求進行控制。
一般這裏不需要我們自己來寫,像eclipse工具可以幫我們自動生成重寫的equals和hashcode方法,直接使用即可,這裏貼上自動生成的代碼,大家看看其實現原理
//重寫的hashcode方法,使其滿足約定
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((city == null) ? 0 : city.hashCode());
result = prime * result + ((province == null) ? 0 : province.hashCode());
return result;
}
//重寫的equals方法,用來比較兩個對象是否相同
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Address other = (Address) obj;
if (city == null) {
if (other.city != null)
return false;
} else if (!city.equals(other.city))
return false;
if (province == null) {
if (other.province != null)
return false;
} else if (!province.equals(other.province))
return false;
return true;
}
最後,附上兩篇講的比較透徹的文章以供大家參考:Java正確的自定義比較對象----如何重寫equals方法和hashcode方法,Java哈希碼以及equals和==的區別
關於重寫對象equals方法的問題