如果在HotSpot Java 7 64位版本上運行以下操作。是否有理由Object.hashCode()是31位?
int countTopBit = 0, countLowestBit = 0;
for (int i = 0; i < 100000000; i++) {
int h = new Object().hashCode();
if (h < 0)
countTopBit++;
if ((h & 1) == 1)
countLowestBit++;
}
System.out.println("The count of negative hashCodes was " + countTopBit + ", the count of odd hashCodes was " + countLowestBit);
你可以像
The count of negative hashCodes was 0, the count of odd hashCodes was 49994232
結果我在想,如果這意味着Object.hashCode()
是唯一真正31位和爲什麼會是這樣?
不是最高位未被使用的情況。從源HashMap中
257 /**
258 * Applies a supplemental hash function to a given hashCode, which
259 * defends against poor quality hash functions. This is critical
260 * because HashMap uses power-of-two length hash tables, that
261 * otherwise encounter collisions for hashCodes that do not differ
262 * in lower bits. Note: Null keys always map to hash 0, thus index 0.
263 */
264 static int hash(int h) {
265 // This function ensures that hashCodes that differ only by
266 // constant multiples at each bit position have a bounded
267 // number of collisions (approximately 8 at default load factor).
268 h ^= (h >>> 20)^(h >>> 12);
269 return h^(h >>> 7)^(h >>> 4);
270 }
這可能是一個優化。哈希表通常將哈希碼mod作爲桶的數量,但必須首先屏蔽掉最高位以避免負索引。也許這是爲了避免後面的那一步? – templatetypedef
@templatetypedef我確實懷疑這可能是這種情況,但我懷疑Object.hashCode()並沒有在哈希集合中使用,因爲它通常被32位hashCode()重寫。此外,HashMap會對原始hashCode進行變異,以便使用最高位。 –
@templatetypedef:但是用戶替代不會這樣做? Hash表仍然需要處理 –