hashCode是jdk根據對象的地址算出來的一個int數字,即對象的哈希碼值,表明了該對象在內存中的存儲位置。數據結構
hashCode()方法是頂級類Object類的提供的一個方法,全部的類均可以進行對hashCode方法重寫。性能
在比較一個類是否相同時每每會重寫equals方法,值得注意的是,重寫equals方法的同時必須也要重寫hashCode方法,屢次調用一個對象的hashCode方法必須返回同一個數字,這也是必須遵照的規範,否則會形成潛在的危害。優化
當兩個對象equals相同,hashCode規定也必須相同,但反過來就不必定,兩個對象對應一個hashCode,但equals卻並不相等。這就是傳說中的hash衝突。spa
HashMap是以hashCode取模數組形式存放值的,那兩個對象hashCode同樣會不會形成前一個對象的值覆蓋呢?答案是不會,由於它採用了另一種鏈表數據結構來解決hash衝突的狀況,即便兩個對象的hashCode同樣,它們會放到當前數組索引位置的鏈表中。設計
HashSet經過HashMap來實現的,用來存儲不重複數據的,怎麼判斷裏面的對象是否重複呢?判斷對象是否重複便是判斷對象裏面的屬性是否都同樣,這時必須是重寫了equals方法去比較對象的裏面全部的值,而不是比較引用地址,比較引用地址它們永遠都不相等,除非是同一個對象。經過equals比較的過程性能是很是不佳的,因此有了hashCode這個設計,簡單兩個數字的比較性equals無法比的,因此能夠先經過比較對象的hashCode是否同樣肯定是否是同一個對象,若是hashCode不同這時確定就不是同一個對象,反之若是hashCode同樣並且equals或者==也同樣這確定就是同一個對象。因此先比較數字的hashCode再比較equals或者==,這樣效率會明顯提高。3d
假如重寫equals而不重寫hashCode方法,多個對象屬性值同樣的它們的hashCode確定是不同的,這時做爲key在put到map中的時候,就會有多個這樣的key,而達不到對象做爲key的場景,一樣也達不到HashSet去重的效果。對象
HashSet經過封裝HashMap實現,用來存儲不重複數據的,怎麼判斷裏面的對象是否重複呢?blog
就是重寫HashSet<E>的對象E的equals方法。若是E的equals方法返回true,那麼就是相同的對象;若是返回false就是不一樣的對象。可是經過equals就是太慢了,有啥優化的辦法嗎?有,先比較E的hashCode,若是hashCode不一樣,那麼就是不一樣的E,由於絕大多數狀況下都是不一樣的E,因此先比較E的hashCode絕對能提升效率的。索引
這裏會出現一個新問題,若是在HashSet的E中重寫了equals方法可是沒重寫hashCode方法的話。Equals實際上相同的對象hashCode可能並不相同,這樣的話以前想到的優化方案【先比較E的hashCode】就失效了。因此必須再想辦法堵住這個bug,就是必須同時重寫hashCode方法,使E的邏輯知足:若是equals方法返回true時,hashCode返回的結果也是相同的。
hashCode是jdk根據對象的地址算出來的一個int數字,即對象的哈希碼值,表明了該對象在內存中的存儲位置。
是何意義?就是說若是Object不一樣,那麼理論上hashCode的值就是不一樣的。
這樣的話若是不重寫E的hashCode方法的話,HashSet比較E是否相同的優化【先比較E的hashCode】就失去意義了——不重寫E的hashCode方法(equals相同的對象)在優化比較時就有可能被濾過去了,HashSet反而存儲了實際上相同的對象,這就亂套了。