2014-11-06 33 views
1

我想知道爲什麼new Integer(i).hashCode()new Long(i).hashCode()返回i但當hashCode()被某個其他對象如new Double(345).hashCode()調用時,它返回一個隨機數。爲什麼?爲什麼新的Integer(i).hashCode()返回i?

+2

閱讀關於'hashCode':http://en.wikipedia.org/wiki/Java_hashCode() – Crozin 2014-11-06 14:13:27

+0

它不會以'Long'的方式工作。嘗試用'i = 2147483648l' – blgt 2014-11-06 14:23:05

+0

如果你閱讀這些方法的源代碼,它應該很明顯,他們爲什麼不能相同。 – 2014-11-06 14:40:32

回答

8

因爲一個Integer完全滿足並與Object.hashCode()一般合同完全符合的int值:

hashCode的一般合同是:

  • 當在Java應用程序的執行過程中,它不止一次會在同一個對象上被調用,如果修改了對象的equals比較中沒有使用的信息,hashCode方法必須始終返回相同的整數。該整數不需要從應用程序的一次執行到同一應用程序的另一次執行保持一致。

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

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

簡而言之:

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

Long

哈希代碼必須映射的8個字節爲4個字節(一個int的大小)。如果它符合的Long.hashCode()當前實現將只返回iint,不然它會與上部32位(4個字節)被異或運算:

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

散列碼的Double

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

Double.hashCode()會返回一個看似隨機值,因爲浮點數(floatdouble)沒有存儲「很好」,在保留給他們,但字節(如intlong例如,2的補碼)使用IEEE 754 binary floating point standard等映射那些8字節到4(這正是實現所做的)將不會是一個有意義的數字,因爲它使用2的補碼錶示形式。

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

整數的值是一個足夠好的散列,因爲它與唯一整數本身一樣唯一。

double必須以某種不同的方式散列,因爲這裏的散列必須是整數。

+0

所以散列總是必須是整數? – mac07 2014-11-06 14:21:25

+0

@ mac07是的,散列碼必須是整數。 – Rohan 2014-11-06 14:23:28

3

becase的的implementation說:

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  } 
+0

@Downvote:爲什麼downvote?請解釋。 – Jens 2014-11-06 14:15:45

1

Java中的不同類型計算散列碼的方式不同,它們都是隨機的。在長整型和Double的情況下,哈希碼是值除了在那裏它被轉換爲int

1

這是雙重的情況下,因爲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)); 
     } 
1

Integer類「盒子」一個原始int值,但它有自己的一個對象引用。如果Object.equals()指出兩個相同的對象AB都必須表現出相同的Object.hashCode(),那麼這樣的哈希碼是前者的int值是合理的。

至於Double,它的值可能會在系統之間改變,這就是爲什麼依靠不同的機制來提供散列碼是有意義的。

相關問題