hashCode概念java
hashCode是jdk根據對象的地址算出來的一個int數字,即對象的哈希碼值,表明了該對象在內存中的存儲位置。數組
咱們都知道hashCode()方法是頂級類Object類的提供的一個方法,全部的類均可以進行對hashCode方法重寫。數據結構
咱們也知道在比較一個類是否相同時每每會重寫equals方法,值得注意的是,重寫equals方法的同時必須也要重寫hashCode方法,屢次調用一個對象的hashCode方法必須返回同一個數字,這也是必須遵照的規範,否則會造必須存在的危害。ide
hash衝突性能
當兩個對象equals相同,hashCode規定也必須相同,但反過來就不必定,兩個對象對應一個hashCode,但equals卻並不相等。。這就是傳說中的hash衝突。HashMap是以hashCode取模數組形式存放值的,那兩個對象hashCode同樣會不會形成前一個對象的值覆蓋呢?答案是不會,由於它採用了另一種鏈表數據結構來解決hash衝突的狀況,即便兩個對象的hashCode同樣,它們會放到當前數組索引位置的鏈表中。spa
hashCode設計設計
HashSet經過HashMap來實現的,用來存儲不重複數據的,怎麼判斷裏面的對象是否重複呢?判斷對象是否重複便是判斷對象裏面的屬性是否都同樣,這時必須是重寫了equals方法去比較對象的裏面全部的值,而不是比較引用地址,比較引用地址它們永遠都不相等,除非是同一個對象。經過equals比較的過程性能是很是不佳的,因此有了hashCode這個設計,簡單兩個數字的比較性equals無法比的,因此能夠先經過比較對象的hashCode是否同樣肯定是否是同一個對象,若是hashCode不同這時確定就不是同一個對象,反之若是hashCode同樣並且equals或者==也同樣這確定就是同一個對象。因此先比較數字的hashCode再比較equals或者==,這樣效率會明顯提高。code
假如咱們重寫了equals而不重寫hashCode方法,多個對象屬性值同樣的它們的hashCode確定是不同的,這時做爲key在put到map中的時候,就會有多個這樣的key,而達不到對象做爲key的場景,一樣也達不到HashSet去重的效果對象
identityHashCode是System裏面提供的本地方法,java.lang.System#identityHashCode。索引
/** * Returns the same hash code for the given object as * would be returned by the default method hashCode(), * whether or not the given object's class overrides * hashCode(). * The hash code for the null reference is zero. * * @param x object for which the hashCode is to be calculated * @return the hashCode * @since JDK1.1 */ public static native int identityHashCode(Object x);
identityHashCode和hashCode的區別是,identityHashCode會返回對象的hashCode,而無論對象是否重寫了hashCode方法。
public static void main(String[] args) { String str1 = new String("abc"); String str2 = new String("abc"); System.out.println("str1 hashCode: " + str1.hashCode()); System.out.println("str2 hashCode: " + str2.hashCode()); System.out.println("str1 identityHashCode: " + System.identityHashCode(str1)); System.out.println("str2 identityHashCode: " + System.identityHashCode(str2)); User user = new User("test", 1); System.out.println("user hashCode: " + user.hashCode()); System.out.println("user identityHashCode: " + System.identityHashCode(user)); }
輸出結果:
str1 hashCode: 96354 str2 hashCode: 96354 str1 identityHashCode: 1173230247 str2 identityHashCode: 856419764 user hashCode: 621009875 user identityHashCode: 621009875
結果分析:
一、str1和str2的hashCode是相同的,是由於String類重寫了hashCode方法,它根據String的值來肯定hashCode的值,因此只要值同樣,hashCode就會同樣。
二、str1和str2的identityHashCode不同,雖然String重寫了hashCode方法,identityHashCode永遠返回根據對象物理內存地址產生的hash值,因此每一個String對象的物理地址不同,identityHashCode也會不同。
三、User對象沒重寫hashCode方法,因此hashCode和identityHashCode返回的值同樣