HashMap 1 8 原始碼閱讀

2021-10-07 16:21:57 字數 3532 閱讀 6451

一、初始化

1.無參建構函式

//負載因子預設值

static final float default_load_factor = 0.75f;

//指定loadfactor負載因子的值是0.75f

public hashmap()

2.指定初始化大小和負載因子

//hashmap的最大容量

static final int maximum_capacity = 1 << 30; //1左移30位等於1073741824

//initialcapacity:傳入的hashmap初始化大小

//loadfactor:負載因子,此時是預設值0.75f

public hashmap(int initialcapacity, float loadfactor)

//返回乙個大於等於initialcapacity的2的n次方最近的乙個值

//假設傳入的initialcapacity=5

static final int tablesizefor(int cap)

3.指定初始化大小(會呼叫2)

//initialcapacity:hashmap初始化大小

public hashmap(int initialcapacity)

二、put元素(轉紅黑樹和put乙個treenode時待補充)

//插入元素

public v put(k key, v value)

//計算hash值

static final int hash(object key)

//hashmap的陣列

transient node table;

//存放資料

final v putval(int hash, k key, v value, boolean onlyifabsent,

boolean evict)

//新增的資料與如果下乙個值的hash值和key相同,直接跳出

if (e.hash == hash &&

((k = e.key) == key || (key != null && key.equals(k))))

break;

//下乙個位置的資料賦值給p,迴圈繼續

p = e;}}

//key存在,更新新值,返回舊值

v oldvalue = e.value;

if (!onlyifabsent || oldvalue == null)

e.value = value;

afternodeaccess(e);

return oldvalue;}}

++modcount;

//判斷是否超過需要的大小

if (++size > threshold)

resize();

afternodeinsertion(evict);

return null;

}//初始化或擴容時呼叫

final node resize()

//新的容量是舊陣列的容量左移以為即:oldcap*2。如果陣列容量大於default_initial_capacity=16時,擴容的容量也要×2

else if ((newcap = oldcap << 1) < maximum_capacity &&

oldcap >= default_initial_capacity)

newthr = oldthr << 1; // double threshold

}//舊陣列為空,進行初始化

else if (oldthr > 0) // 初始化容量設定為threshold(需要擴容的值)

newcap = oldthr;

else

//新的threshold(需要擴容的大小)為零時,newthr=newcap * loadfactor

if (newthr == 0)

//賦值回threshold

threshold = newthr;

@suppresswarnings()

//定義乙個新hashmap的陣列,值是新的容量

node newtab = (node)new node[newcap];

table = newtab;

//舊陣列不為空,擴容

if (oldtab != null)

else

} while ((e = next) != null);

//將當前陣列位置下的鍊錶(hihead/lohead)放到新陣列的(當前陣列位置+oldcap)位置

//lotail/hitail.next設定為空為了防止lotail和lohead(或hihead和hitail)指向同乙個位址時資料重複,

//重複時則清除lohead和hihead的next值

if (lotail != null)

if (hitail != null) }}

}}

return newtab;

}

、get元素

//返回鍵對應的值

public v get(object key)

//計算hash值

static final int hash(object key)

//根據key獲得對應的node

final nodegetnode(int hash, object key) while ((e = e.next) != null);}}

return null;

}

、remove元素

//返回鍵對應的值

public v remove(object key)

//計算hash值

static final int hash(object key)

//value:如果是matchvalue則需要傳入

//matchvalue:如果等於true則還需要匹配值也相等

//movable:如果為false則在刪除時不要移動其他節點

final noderemovenode(int hash, object key, object value,boolean matchvalue, boolean movable)

p = e;

} while ((e = e.next) != null);}}

//找到元素,並且matchvalue=false或者找到的node的value與指定value相等

if (node != null && (!matchvalue || (v = node.value) == value || (value != null && value.equals(v))))

}return null;

}

HashMap1 8原始碼分析

1 hashmap的原理,內部資料結構如何?底層使用雜湊表 陣列 鍊錶 當鍊表過長 其實是大於8 的時候會將鍊錶轉換成紅黑樹,以實現n log n 的查詢。2 具體過程 對 key 求 hash 值,然後再計算 下標。如果沒有碰撞,直接放入桶中,如果碰撞了,以鍊錶的方式鏈結到後面,如果鍊錶長度超過閥...

原始碼分析 HashMap 1 8

1.0 資料結構 2.0 儲存流程 3.0 陣列元素 鍊錶節點的實現類 hashmap中的陣列元素 鍊錶節點 採用node類 實現,與jdk1.7相比只是把entry換了個名字 hashmap中的紅黑樹節點 採用treenode類 實現 紅黑樹節點 實現類 繼承自linkedhashmap.entr...

JDK原始碼分析系列 HashMap 1 8

預設的初始化容量,必須是2的n次冪 static final int default initial capacity 1 4 aka 16 最大的容量是2的30次冪 static final int maximum capacity 1 30 預設的負載因子 static final float ...