1)hashseed:用於鍵的雜湊碼計算上,用於減少雜湊衝突。通過下面所述的inithashseedasneeded方法來進行初始化
2)threshold:表示可以存放的最大量,它的值為loadfactory*陣列容量,但是存在最大值為1<<30+1【即2^30+1】
3)loadfactory:負載因子,用於表示元素數量超過陣列容量多少時,就會擴容,值在(0,1)之間
4)modcount:每進行一次集合的元素修改,就會進行加1【但是元素的替換並不算集合元素修改之內】
*
1、inithashseedasneeded:用於初始化hashseed
final boolean inithashseedasneeded(int capacity)
return switching;
}
2、inflatetable:進行陣列的初始化,並且會使用上述方法進行hashseed的初始化
private void inflatetable(int tosize)
3、get方法在呼叫時會先判斷key是否為null,key==null,就會呼叫getfornullkey方法,否則使用getentry方法
getfornullkey方法:
private v getfornullkey()
for (entrye = table[0]; e != null; e = e.next)
return null;
}getentry方法:
public entrygetentry(object key)
int hash = key==null?0:hash(key);
//找到key儲存的對應的entry
entryentries = table[indexfor(hash,table.length)];
for(; entries!=null ; entries = entries.next)
}return null;
}
3、put:進行元素的新增或者元素替換,key值相同會進行值替換,但是如果進行元素新增,會呼叫addentry方法
public v put(k key,v value)
if(key==null)
int hash = hash(key);
//判斷當前是否具有key是傳入的key,如果有就直接進行值替換
for(entryentry=table[indexfor(hash,table.length)] ; entry!=null ; entry = entry.next)
}//如果不是進行元素替換,肯定會進行修改,所以修改次數加1
modcount++;
//進行元素的新增
addentry(hash,key,value,indexfor(hash,table.length));
return null;
}
4、putforcreate:也是進行元素的新增,但是方法並不對外開放。新增元素也不會進行modcount的自增。同樣新增元素時,會使用createentry方法進行新增
//不會去檢查是否超過閾值,直接計算
private void putforcreate(k key,v value)
}//也是增加節點
createentry(hash,key,value,bucketindex);
}
5、addentry方法:進行元素的增加,同時會判斷是否需要進行擴容
createentry方法:也是進行元素的新增,但是並不會進行擴容的判斷
//增加元素,並且判斷是否超過閾值
void addentry(int hash,k key,v value,int bucketindex)
createentry(hash,key,value,bucketindex);
}//無需判斷是否超過閾值,直接新增元素
void createentry(int hash,k key,v value,int bucketindex)
6、//刪除元素
public v remove(object key)
//真正進行節點刪除的方法
final entryremoveentryforkey(object key)
int hash = key==null?0:hash(key);
int bucketindex = indexfor(hash,table.length);
entrye = table[bucketindex];
entrypre = e;
while(e!=null)else
}pre = e;
e = next;
}return e;
}
7、resize:進行陣列的擴容
transfer:進行陣列擴容之後的調整
//進行擴容
void resize(int newcapacity)
entry newtable = new entry[newcapacity];
//進行陣列調整
transfer(newtable,inithashseedasneeded(newcapacity));
table = newtable;
//進行閾值的重新計算
threshold = (int)math.min(newcapacity*loadfactor,maxmun_capacity+1);
}//進行擴容之後的老陣列與新陣列的裝填
void transfer(entry newtable,boolean rehash)
//獲取到對應的陣列位置
int i = indexfor(entry.hash,newcapacity);
entry.next = newtable[i];
newtable[i] = entry;
entry.next = next;}}
}
總結一下:hashmap的陣列並不是在初始化的時候就會進行構建的,而是在需要的時候才會進行構建 HashMap 1 7和1 8的區別
底層資料結構不一樣,1.7是陣列 鍊錶,1.8則是陣列 鍊錶 紅黑樹結構 當鍊表長度大於8,轉為紅黑樹 jdk1.7用的是頭插法,而jdk1.8及之後使用的都是尾插法,那麼他們為什麼要這樣做呢?因為jdk1.7是用單鏈表進行的縱向延伸,當採用頭插法時會容易出現逆序且環形鍊錶死迴圈問題。但是在jdk1...
1 7 HashMap原始碼分析
1.7 hashmap原始碼分析,最近準備面試,整理一下知識點,雖然hashmap的原始碼在網上都已經快翻爛了,但是自己再寫一遍也會加深一下記憶,再走一遍原始碼,就感覺hashmap是自己寫的對不對!之後我也會分析一下1.8的hashmap的原始碼!好了 屁話不多說,開始我們原始碼分析!1.基本屬性...
JDK1 7HashMap原始碼解析
hashmap已經看了很多篇文章了,今天還是自己解析一遍吧。我先大致介紹下hashmap的內部結構再跟著原始碼解讀一番 眾所周知hashmap的內部就是乙個雜湊表 什麼是雜湊表?如果我們利用陣列可隨機訪問的特性,將要存入的鍵通過一種雜湊演算法轉換成乙個數字,並把這個數字轉換成陣列的下標,然後將鍵和他...