HashMap 1 7 原始碼講解

2021-10-05 05:30:00 字數 3141 閱讀 9729

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的內部就是乙個雜湊表 什麼是雜湊表?如果我們利用陣列可隨機訪問的特性,將要存入的鍵通過一種雜湊演算法轉換成乙個數字,並把這個數字轉換成陣列的下標,然後將鍵和他...