程序員必須搞清的概念-equals和=和hashcode的區別

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 方法的常規協定,javascript

該協定聲明相等對象必須具備相等的哈希碼。

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

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() 的做用是 用來判斷兩個對象是否相等。java

equals() 定義在JDK的Object.java中。經過判斷兩個對象的地址是否相等(即,是不是同一個對象)來區分它們是否相等。數組

源碼以下:

public boolean equals(Object obj) {
    return (this == obj);
}

下面根據「類是否覆蓋equals()方法」,將它分爲2類。

(01) 若某個類沒有覆蓋equals()方法,當它的經過equals()比較兩個對象時,其實是比較兩個對象是否是同一個對象。這時,等價於經過「==」去比較這兩個對象。markdown

(02) 咱們能夠覆蓋類的equals()方法,來讓equals()經過其它方式比較兩個對象是否相等。一般的作法是:若兩個對象的內容相等,則equals()方法返回true;不然,返回fasle。數據結構

3. equals() 與 == 的區別

== : 它的做用是判斷兩個對象的地址是否是相等。即,判斷兩個對象是不試同一個對象。app

equals() : 它的做用也是判斷兩個對象是否相等。但它通常有兩種使用狀況

狀況1,

類沒有覆蓋equals()方法。則經過equals()比較該類的兩個對象時,等價於經過「==」比較這兩個對象。ide

狀況2,

類覆蓋了equals()方法。通常,咱們都覆蓋equals()方法來兩個對象的內容相等;若它們的內容相等,則返回true(即,認爲這兩個對象相等)。函數

4.hashCode() 的做用

hashCode() 的做用是獲取哈希碼,也稱爲散列碼;它其實是返回一個int整數。這個哈希碼的做用是肯定該對象在哈希表中的索引位置。this

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

雖然,每一個Java類都包含hashCode() 函數。可是,僅僅當建立並某個「類的散列表」(關於「散列表」見下面說明)時,該類的hashCode() 纔有用(做用是:肯定該類的每個對象在散列表中的位置;其它狀況下(例如,建立類的單個對象,或者建立類的對象數組等等),類的hashCode() 沒有做用。

上面的散列表,指的是:

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

也就是說:hashCode() 在散列表中才有用,在其它狀況下沒用。在散列表中hashCode() 的做用是獲取對象的散列碼,進而肯定該對象在散列表中的位置。

hashCode()的做用是獲取散列碼。

5. hashCode() 和 equals() 的關係

1. 第一種 不會建立「類對應的散列表」

這裏所說的「不會建立類對應的散列表」是說:咱們不會在HashSet, Hashtable, HashMap等等這些本質是散列表的數據結構中,用到該類。例如,不會建立該類的HashSet集合。

在這種狀況下,該類的「hashCode() 和 equals() 」沒有關係的

這種狀況下,equals() 用來比較該類的兩個對象是否相等。而hashCode() 則根本沒有任何做用,因此,不用理會hashCode()。

下面,咱們經過示例查看類的兩個對象相等 以及 不等時hashCode()的取值。

2. 第二種 會建立「類對應的散列表」

這裏所說的「會建立類對應的散列表」是說:咱們會在HashSet, Hashtable, HashMap等等這些本質是散列表的數據結構中,用到該類。例如,會建立該類的HashSet集合。

在這種狀況下,該類的「hashCode() 和 equals() 」是有關係的:

一、若是兩個對象相等,那麼它們的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/

<script type="text/javascript"> $(function () { $('pre.prettyprint code').each(function () { var lines = $(this).text().split('\n').length; var $numbering = $('<ul/>').addClass('pre-numbering').hide(); $(this).addClass('has-numbering').parent().append($numbering); for (i = 1; i <= lines; i++) { $numbering.append($('<li/>').text(i)); }; $numbering.fadeIn(1700); }); }); </script>
相關文章
相關標籤/搜索