Object.hashCode()方法與System.identityHashCode(object)的區別

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

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返回的值同樣

相關文章
相關標籤/搜索