== 和equals()和hashcode()區別與聯繫

一:==和equals()比較算法

     值類型是存儲在內存中的棧,而引用類型的變量在棧中僅僅是存儲引用類型變量的地址,而其自己則存儲在堆中。spa

    ==操做比較的是兩個變量的值是否相等,對於引用型變量表示的是兩個變量在堆中存儲的地址是否相同,即棧中的內容是否相同。設計

    equals操做表示的兩個變量是不是對同一個對象的引用,即堆中的內容是否相同。code

    1:【簡單數據類型和封裝類中的equals和==】==比較的是2個對象的地址,而equals比較的是2個對象的內容。對象

    2:其餘類怎麼使用equals和==繼承

    API裏的類大部分都重寫了equals方法,沒有重寫的通常是本身寫的類,若是是你本身定義的一個類,比較自定義類用equals和==是同樣的,都是比較句柄地址,由於自定義的類是繼承於object,而object中的equals就是用==來實現的,你能夠看源碼內存

    顯然,當equals爲true時,==不必定爲true;源碼

 

equals()反映的是對象或變量具體的值,即兩個對象裏面包含的值--多是對象的引用,也多是值類型的值。hash

而hashCode()是對象或變量經過哈希算法計算出的哈希值。table

之因此有hashCode方法,是由於在批量的對象比較中,hashCode要比equals來得快,不少集合都用到了hashCode,好比HashTable。

 

兩個obj,若是equals()相等,hashCode()必定相等。

兩個obj,若是hashCode()相等,equals()不必定相等(Hash散列值有衝突的狀況,雖然機率很低)。

因此:

能夠考慮在集合中,判斷兩個對象是否相等的規則是:

第一步,若是hashCode()相等,則查看第二步,不然不相等;

第二步,查看equals()是否相等,若是相等,則兩obj相等,不然仍是不相等

 

 

一.hashCode方法的做用

  對於包含容器類型的程序設計語言來講,基本上都會涉及到hashCode。在Java中也同樣,hashCode方法的主要做用是爲了配合基於散列的集合一塊兒正常運行,這樣的散列集合包括HashSet、HashMap以及HashTable。

  爲何這麼說呢?考慮一種狀況,當向集合中插入對象時,如何判別在集合中是否已經存在該對象了?(注意:集合中不容許重複的元素存在)

  也許大多數人都會想到調用equals方法來逐個進行比較,這個方法確實可行。可是若是集合中已經存在一萬條數據或者更多的數據,若是採用equals方法去逐一比較,效率必然是一個問題。此時hashCode方法的做用就體現出來了,當集合要添加新的對象時,先調用這個對象的hashCode方法,獲得對應的hashcode值,實際上在HashMap的具體實現中會用一個table保存已經存進去的對象的hashcode值,若是table中沒有該hashcode值,它就能夠直接存進去,不用再進行任何比較了;若是存在該hashcode值, 就調用它的equals方法與新元素進行比較,相同的話就不存了,不相同就散列其它的地址,因此這裏存在一個衝突解決的問題,這樣一來實際調用equals方法的次數就大大下降了,說通俗一點:Java中的hashCode方法就是根據必定的規則將與對象相關的信息(好比對象的存儲地址,對象的字段等)映射成一個數值,這個數值稱做爲散列值。

  若是equals方法獲得的結果爲false,則兩個對象的hashcode值不必定不一樣;

  若是兩個對象的hashcode值不等,則equals方法獲得的結果一定爲false;

  若是兩個對象的hashcode值相等,則equals方法獲得的結果未知。

二.equals方法和hashCode方法

  在有些狀況下,程序設計者在設計一個類的時候爲須要重寫equals方法,好比String類,可是千萬要注意,在重寫equals方法的同時,必須重寫hashCode方法。

  下面這段話摘自Effective Java一書:  這樣一來的話,輸出結果就爲「1」了。

  • 在程序執行期間,只要equals方法的比較操做用到的信息沒有被修改,那麼對這同一個對象調用屢次,hashCode方法必須始終如一地返回同一個整數。
  • 若是兩個對象根據equals方法比較是相等的,那麼調用兩個對象的hashCode方法必須返回相同的整數結果。
  • 若是兩個對象根據equals方法比較是不等的,則hashCode方法不必定得返回不一樣的整數。

  以上屬我的理解,若有不正之處,歡迎批評指正。

相關文章
相關標籤/搜索