一:==和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。在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方法,好比String類,可是千萬要注意,在重寫equals方法的同時,必須重寫hashCode方法。
下面這段話摘自Effective Java一書: 這樣一來的話,輸出結果就爲「1」了。
以上屬我的理解,若有不正之處,歡迎批評指正。