原文 https://blog.csdn.net/sd_csdn_scy/article/details/57083619
hashMap源碼獲取元素的位置:
static int indexFor(int h, int length) { // assert Integer.bitCount(length) == 1 : "length must be a non-zero power of 2"; return h & (length-1); }
解釋:
h:為插入元素的hashcode
length:為map的容量大小
&:與操作 比如 1101 & 1011=1001
如果length為2的次冪 則length-1 轉化為二進制必定是11111……的形式,在於h的二進制與操作效率會非常的快,
而且空間不浪費;如果length不是2的次冪,比如length為15,則length-1為14,對應的二進制為1110,在於h與操作,
最后一位都為0,而0001,0011,0101,1001,1011,0111,1101這幾個位置永遠都不能存放元素了,空間浪費相當大,更糟的是這種情況中,數組可以使用的位置比數組長度小了很多,這意味着進一步增加了碰撞的幾率,減慢了查詢的效率!這樣就會造成空間的浪費
PS: 這都是老版本jdk的源碼,1.7,8之后都沒有這個方法了, 但是計算位置index的思想不變,就是要充分散列,減少碰撞
下面是1.8的代碼
final V putVal(int hash, K key, V value, boolean onlyIfAbsent, boolean evict) { Node<K,V>[] tab; Node<K,V> p; int n, i; if ((tab = table) == null || (n = tab.length) == 0) n = (tab = resize()).length; if ((p = tab[i = (n - 1) & hash]) == null) //計算index tab[i] = newNode(hash, key, value, null);