簡體   English   中英

為什么新的Integer(i).hashCode()返回i?

[英]why does new Integer(i).hashCode() return i?

我想知道為什么new Integer(i).hashCode()new Long(i).hashCode()返回i但是當其他對象調用hashCode()時說new Double(345).hashCode() ,則返回一個隨機數。 為什么?

因為Integerint值完全滿足並且完全符合Object.hashCode()的常規協定:

hashCode的一般約定為:

  • 在Java應用程序的執行過程中,只要在同一對象上多次調用它,則hashCode方法必須一致地返回相同的整數,前提是未修改該對象的equals比較中使用的信息。 從一個應用程序的執行到同一應用程序的另一執行,此整數不必保持一致。

  • 如果根據equals(Object)方法,兩個對象相等,則在兩個對象中的每個對象上調用hashCode方法必須產生相同的整數結果。

  • 根據equals(java.lang.Object)方法,如果兩個對象不相等,則不需要在兩個對象中的每個對象上調用hashCode方法必須產生不同的整數結果。 但是,程序員應該意識到,為不相等的對象生成不同的整數結果可能會提高哈希表的性能。

簡而言之:

2個對象的散列碼必須是相同的,如果equals()返回true ,當且應該 (但不是必須的)不同的equals()返回false 同樣通過Object.hashCode()的聲明,它必須是int 理想情況下,哈希碼應取決於所有哈希數據。

Long哈希碼

Long必須將8個字節映射為4個字節( int大小)。 如果Long.hashCode()當前實現適合int ,則僅返回i ,否則將與高32位(4個字節)進行XOR運算:

return (int)(value ^ (value >>> 32));

Double哈希碼

顯然, Doubledouble值不符合此條件。 Double還必須將8個字節映射到4個字節。

Double.hashCode()將返回一個看似隨機的值,因為浮點數( floatdouble )不會“漂亮地”存儲(例如,像intlong這樣的2的補碼),但為它們保留的字節中卻使用IEEE 754二進制浮點數標准等映射那些8個字節到4(這是完全執行的作用)將不會是一個有意義的號碼作為int它采用2的補碼表示。

long bits = doubleToLongBits(value);
return (int)(bits ^ (bits >>> 32));

整數值足以滿足要求,因為它與唯一整數本身一樣唯一。

必須以某種不同的方式對double進行哈希處理,因為此處的哈希必須為整數。

假設實現如下:

Returns a hash code for this Integer. 

Returns:a hash code value for this object, equal to the primitive int value represented by this Integer object.

707
708     public int hashCode() {
709         return value;
710     }

Java中的不同類型以不同的方式計算哈希碼,它們都不是隨機的。 對於Long Integer和Double,哈希碼是值,但對於Double,則將其轉換為int

這是因為Integer類的hashcode()方法將值作為哈希碼返回。

 Returns a hash code for this <code>Integer</code>.

 @return  a hash code value for this object, equal to the 
          primitive <code>int</code> value represented by this 
          <code>Integer</code> object. 

public int hashCode() {
return value;
}

Double類的hashcode()方法執行一些操作並返回哈希碼。

    Returns a hash code for this Double object. The result is the exclusive OR 
    of the two halves of the long integer bit representation, exactly as produced by
    the  method  {@link #doubleToLongBits(double)}, of the primitive double value 
    represented by this Double object. That is, the hash code is the value of the
    expression:

        public int hashCode() {
        long bits = doubleToLongBits(value);
        return (int)(bits ^ (bits >>> 32));
        }

Integer類將原始int值“裝箱”,但是它具有自己的對象引用。 如果Object.equals()聲明兩個相等的對象AB必須都表現出相同的Object.hashCode() ,則將此類哈希碼設為前一個int值是有意義的。

至於Double ,它的值可能在系統之間改變,這就是為什么依靠不同的機制來提供哈希碼是有意義的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM