程式設計師必須搞清的概念equals和=和hashcode的區別

jamesehng發表於2016-12-09
  1. 首先equals()和hashcode的介紹 ==============================================

equals 方法在非空物件引用上實現相等關係:

 * 自反性:對於任何非空引用值 x,x.equals(x) 都應返回 true。
 * 對稱性:對於任何非空引用值 x 和 y,當且僅當 y.equals(x) 返回 true 時,x.equals(y) 才應返回 true。
 * 傳遞性:對於任何非空引用值 x、y 和 z,如果 x.equals(y) 返回 true,
  並且 y.equals(z) 返回 true,那麼 x.equals(z) 應返回 true。
 * 一致性:對於任何非空引用值 x 和 y,多次呼叫 x.equals(y) 始終返回 true 或始終返回 false,
  前提是物件上 equals 比較中所用的資訊沒有被修改。
 * 對於任何非空引用值 x,x.equals(null) 都應返回 false。 
複製程式碼

hashcode

注意1:當此方法被重寫時,通常有必要重寫 hashCode 方法,以維護 hashCode 方法的常規協定,

該協定宣告相等物件必須具有相等的雜湊碼。

但是我們必需清楚,當String 、Math、還有Integer、Double。。。。等這些封裝類在使用equals()方法時, 已經覆蓋了object類的equals()方法。比如在String類中如下:

public boolean equals(Object anObject) {
  if (this == anObject) {
   return true;
  }
  if (anObject instanceof String) {
    String anotherString = (String)anObject;
    int n = count;
    if (n == anotherString.count) {
    char v1[] = value;
    char v2[] = anotherString.value;
    int i = offset;
    int j = anotherString.offset;
    while (n-- != 0) {
     if (v1[i++] != v2[j++])
      return false;
    }
    return true;
   }
  }
  return false;
 }
複製程式碼

注意:以上這五點是重寫equals()方法時,必須遵守的準則,如果違反會出現意想不到的結果

2.equals() 的作用

equals() 的作用是 用來判斷兩個物件是否相等。

equals() 定義在JDK的Object.java中。通過判斷兩個物件的地址是否相等(即,是否是同一個物件)來區分它們是否相等。

原始碼如下:

public boolean equals(Object obj) {
    return (this == obj);
}
複製程式碼

下面根據“類是否覆蓋equals()方法”,將它分為2類。

(01) 若某個類沒有覆蓋equals()方法,當它的通過equals()比較兩個物件時,實際上是比較兩個物件是不是同一個物件。這時,等價於通過“==”去比較這兩個物件。

(02) 我們可以覆蓋類的equals()方法,來讓equals()通過其它方式比較兩個物件是否相等。通常的做法是:若兩個物件的內容相等,則equals()方法返回true;否則,返回fasle。

  1. equals() 與 == 的區別 == == : 它的作用是判斷兩個物件的地址是不是相等。即,判斷兩個物件是不試同一個物件。

equals() : 它的作用也是判斷兩個物件是否相等。但它一般有兩種使用情況

情況1,

類沒有覆蓋equals()方法。則通過equals()比較該類的兩個物件時,等價於通過“==”比較這兩個物件。

情況2,

類覆蓋了equals()方法。一般,我們都覆蓋equals()方法來兩個物件的內容相等;若它們的內容相等,則返回true(即,認為這兩個物件相等)。

4.hashCode() 的作用

hashCode() 的作用是獲取雜湊碼,也稱為雜湊碼;它實際上是返回一個int整數。這個雜湊碼的作用是確定該物件在雜湊表中的索引位置。

hashCode() 定義在JDK的Object.java中,這就意味著Java中的任何類都包含有hashCode() 函式。

雖然,每個Java類都包含hashCode() 函式。但是,僅僅當建立並某個“類的雜湊表”(關於“雜湊表”見下面說明)時,該類的hashCode() 才有用(作用是:確定該類的每一個物件在雜湊表中的位置;其它情況下(例如,建立類的單個物件,或者建立類的物件陣列等等),類的hashCode() 沒有作用。

上面的雜湊表,指的是:

Java集合中本質是雜湊表的類,如HashMap,Hashtable,HashSet。

也就是說:hashCode() 在雜湊表中才有用,在其它情況下沒用。在雜湊表中hashCode() 的作用是獲取物件的雜湊碼,進而確定該物件在雜湊表中的位置。

hashCode()的作用是獲取雜湊碼。

  1. hashCode() 和 equals() 的關係 ==

  2. 第一種 不會建立“類對應的雜湊表”


這裡所說的“不會建立類對應的雜湊表”是說:我們不會在HashSet, Hashtable, HashMap等等這些本質是雜湊表的資料結構中,用到該類。例如,不會建立該類的HashSet集合。

在這種情況下,該類的“hashCode() 和 equals() ”沒有關係的

這種情況下,equals() 用來比較該類的兩個物件是否相等。而hashCode() 則根本沒有任何作用,所以,不用理會hashCode()。

下面,我們通過示例檢視類的兩個物件相等 以及 不等時hashCode()的取值。

  1. 第二種 會建立“類對應的雜湊表”

這裡所說的“會建立類對應的雜湊表”是說:我們會在HashSet, Hashtable, HashMap等等這些本質是雜湊表的資料結構中,用到該類。例如,會建立該類的HashSet集合。

在這種情況下,該類的“hashCode() 和 equals() ”是有關係的:

1、如果兩個物件相等,那麼它們的hashCode()值一定相同。 這裡的相等是指,通過equals()比較兩個物件時返回true。

2.、如果兩個物件hashCode()相等,它們並不一定相等。 因為在雜湊表中,hashCode()相等,即兩個鍵值對的雜湊值相等。然而雜湊值相等,並不一定能得出鍵值對相等。補充說一句:“兩個不同的鍵值對,雜湊值相等”,這就是雜湊衝突。

此外,在這種情況下。若要判斷兩個物件是否相等,除了要覆蓋equals()之外,也要覆蓋hashCode()函式。否則,equals()無效。

例如,建立Person類的HashSet集合,必須同時覆蓋Person類的equals() 和 hashCode()方法。

如果單單只是覆蓋equals()方法。我們會發現,equals()方法沒有達到我們想要的效果。

參考:

http://www.cnblogs.com/skywang12345/p/3324958.html http://hubingforever.blog.163.com/blog/static/1710405792010751168502/

相關文章