JDK1.8中,對HashMap的hash算法和尋址算法有何優化?
HashMap源碼
1. hash(Object key)算法
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); }
h = key.hashCode() 表示 h 是 key 對象的 hashCode 返回值;
h >>> 16 是 h 右移 16 位,因為 int 是 4 字節,32 位,所以右移 16 位后變成:左邊 16 個 0 + 右邊原 h 的高 16 位;最后把這兩個進行異或返回。
異或:二進制位運算。如果一樣返回 0,不一樣則返回 1。 例:兩個二進制 110 和 100 進行異或 110 ^ 100 結果= 010
hash算法的優化:對每個hash值,在它的低16位中,讓高低16位進行異或,讓它的低16位同時保持了高低16位的特征,盡量避免一些hash值后續出現沖突,大家可能會進入數組的同一位置。
2.putVal() 中尋址部分
(p = tab[i = (n - 1) & hash]) == null
tab 就是 HashMap 里的 table 數組 Node<K,V>[] table ;
n 是這個數組的長度 length;
hash 就是上面 hash() 方法返回的值;
尋址算法的優化:用與運算替代取模,提升性能。(由於計算機對比取模,與運算會更快)
課外鏈接:https://www.cnblogs.com/eycuii/p/12015283.html