1. 程式人生 > >關於重寫對象equals方法的問題

關於重寫對象equals方法的問題

left over 集合 相等 res 重復 cli ips lan

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方法的問題