我想知道爲什麼new Integer(i).hashCode()
或new Long(i).hashCode()
返回i
但當hashCode()
被某個其他對象如new Double(345).hashCode()
調用時,它返回一個隨機數。爲什麼?爲什麼新的Integer(i).hashCode()返回i?
回答
因爲一個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()
當前實現將只返回i
成int
,不然它會與上部32位(4個字節)被異或運算:
return (int)(value^(value >>> 32));
散列碼的Double
顯然Double
的double
值不符合此條件。 Double
也必須映射8個字節到4個字節。
Double.hashCode()
會返回一個看似隨機值,因爲浮點數(float
和double
)沒有存儲「很好」,在保留給他們,但字節(如int
或long
例如,2的補碼)使用IEEE 754 binary floating point standard等映射那些8字節到4(這正是實現所做的)將不會是一個有意義的數字,因爲它使用2的補碼錶示形式。
long bits = doubleToLongBits(value);
return (int)(bits^(bits >>> 32));
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 }
@Downvote:爲什麼downvote?請解釋。 – Jens 2014-11-06 14:15:45
Java中的不同類型計算散列碼的方式不同,它們都是隨機的。在長整型和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()
指出兩個相同的對象A
和B
都必須表現出相同的Object.hashCode()
,那麼這樣的哈希碼是前者的int
值是合理的。
至於Double
,它的值可能會在系統之間改變,這就是爲什麼依靠不同的機制來提供散列碼是有意義的。
- 1. Integer i = 3 vs Integer i = new Integer(3)
- 2. 爲什麼RecyclerView.getChildAt(i)和Recycler.getLayoutManager()。getChildAt(i)返回不同的視圖
- 3. 爲什麼對於(int i = 0; i <10; ++ i)和for(int i = 0; i <10; i ++)返回相同?
- 4. 爲什麼Array(100).map((_,i)=> i + 1)不返回[1,2,...,100]?
- 5. 爲什麼i = i + 1比i ++快?
- 6. i = i ++不增加i。爲什麼?
- 7. 什麼是返回void 0 === i &&(i = 3),0 ===我? (..A ..):(..B ..)呢?
- 8. i(i == -i && i!= 0)的值在Java中返回true
- 9. 爲什麼'int i = i;'法律?
- 10. 爲什麼-i ++和 - (i ++)不同?爲什麼結果如下?
- 11. 爲什麼人們使用i = i + 1而不是i ++?
- 12. 爲什麼「for(i = 100; i <= 0; --i)」永遠循環?
- 13. 爲什麼「for($ i = 1; $ i -le 1000000; $ i ++){}」的執行時間快於「for([int] $ i = 1; $ i -le 1000000; $ i ++){}」在PowerShell中
- 14. $ string [i]不返回第i個字符
- 15. 爲什麼(Integer)1 ==(Integer)1返回true,但(Integer)200 ==(Integer)200返回false?
- 16. var i返回undefined?
- 17. 爲什麼「for(; i <= 10; i ++)」工作,但「for(i = 0; i <= 10 ;;)」不?
- 18. 當i = 10時,爲什麼輸出「未定義」(i = 0; i <10; i ++)?
- 19. 爲什麼在for循環中「++ i」和「i ++」有什麼區別?
- 20. i +++ i的價值是什麼?
- 21. 爲什麼printf(「%d%d%d」,++ i,i,i ++)是未定義的行爲?
- 22. 爲什麼i ++先發生?
- 23. 爲什麼DiskLruImageCache塊I/O
- 24. 爲什麼v [i] = i ++在C中是未定義的行爲?
- 25. 爲什麼我們用雙引號返回i +「」;
- 26. 爲什麼mycourses [i] .getGrade()不返回任何東西(C++)?
- 27. out [i] = *(a_mat + i)在C中做什麼?
- 28. i ++和++ i有什麼區別?
- 29. --i和i--有什麼區別?
- 30. 在JavaScript中,「i = + i」是什麼意思?
閱讀關於'hashCode':http://en.wikipedia.org/wiki/Java_hashCode() – Crozin 2014-11-06 14:13:27
它不會以'Long'的方式工作。嘗試用'i = 2147483648l' – blgt 2014-11-06 14:23:05
如果你閱讀這些方法的源代碼,它應該很明顯,他們爲什麼不能相同。 – 2014-11-06 14:40:32