/**
* Computes key.hashCode() and spreads (XORs) higher bits of hash
* to lower. Because the table uses power-of-two masking, sets of
* hashes that vary only in bits above the current mask will
* always collide. (Among known examples are sets of Float keys
* holding consecutive whole numbers in small tables.) So we
* apply a transform that spreads the impact of higher bits
* downward. There is a tradeoff between speed, utility, and
* quality of bit-spreading. Because many common sets of hashes
* are already reasonably distributed (so don't benefit from
* spreading), and because we use trees to handle large sets of
* collisions in bins, we just XOR some shifted bits in the
* cheapest possible way to reduce systematic lossage, as well as
* to incorporate impact of the highest bits that would otherwise
* never be used in index calculations because of table bounds.
*/
static final int hash(Object key) {
int h;
return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
}
該段註釋在hash()方法上。
通過hashCode()方法,計算得到key的hash值,並將近右移16位使其高16位與原hashcode進行異或(hash值本爲32位的int類型)。
之所以需要右移16位,是因爲散列表的大小都是2的階乘,如果不將高位與低位進行異或將會造成持續的hash碰撞。
(原因在於當散列表足夠小的時候,在計算存放位置的時候,參與比較的將只有低位,那麼高位的hash碼將會失去意義,導致大量碰撞產生)
一個顯而易見的例子就是一批Float類型的數據將會在一個小數據量的散列表中造成持續碰撞。所以在這裏將會通過把高位下移的方式來轉換,這是一種對於速度和實用之間的妥協。
相比持續碰撞後採用樹來保存大量hash碰撞的數據,右移幾位進行異或的代價其實很小,也解決了高位的hash不會在小數據量的散列表中進行位置計算的問題。