使用鍊錶 陣列,手寫HashMap

2021-10-09 03:36:57 字數 2056 閱讀 8663

在jdk1.7版本的hashmap 底層採用了鍊錶+陣列的方式實現資料的儲存及擴容等,在jdk1.8後hashmap的底層換為紅黑樹+陣列的方式。這邊以鍊錶+陣列的方式模仿原始碼寫乙個自己的簡易hashmap。

其中初始容量設為的10,負載因子設定0.5,上面效果已有了擴容的效果。

因為是基於鍊錶+陣列實現的,所以要定義乙個node鍊錶陣列,有陣列肯定需要定義陣列的大小,這裡預設是10,原始碼預設是16。看過原始碼的肯定知道還要設定乙個負載因子,定義容量達到多少的時候開始進行擴容,比如初始容量10,負載因子為0.5,則儲存容量達到50%時要進行擴容。

put資料時,先判斷儲存容量有沒有達到負載因子定義的擴容大小,如果沒有達到,則拿到key的hashcode值,採用hashcode%陣列大小獲得儲存位置下標,也就是具體存到前面定義的陣列的某個位置,先判斷該位置是否已經存有值,如果沒有直接將node物件付給該位置,如果已經存有值,則要從第乙個node 一直取next 下乙個node,並判斷key是否相等,相等則覆蓋,沒有則在最後乙個node後新增node。

如果上面put時達到了擴容的大小,則新建乙個node鍊錶陣列,大小為上面鍊錶的兩倍,所有資料都要移到新的鍊錶陣列中,陣列的大小發生了變化,那上面計算的hashcode%陣列大小也發生了變化,所以資料放到新的陣列中,需要重新計算其下標位置。

使用者獲取資料,同樣先拿到hashcode%陣列大小,定位在那個鍊錶中,然後再next 判斷key,拿到就將value返還給使用者。

class node

public k getkey()

public v getvalue()

public v setvalue(v value)

}

這裡就實現put,get,size功能

public inte***ce bxcmap
//鍊錶的陣列

node table = null;

//儲存資料個數

int size;

//負載因子

float default_load_factor = 0.5f;

//初始大小

static int default_initial_capacity = 10;

public v put(k key, v value) 

//判斷是否需要擴容

if (size > (default_load_factor * default_initial_capacity))

//拿到下標的位置

int index = getindex(key, default_initial_capacity);

nodenode = table[index];

//如果該位置沒有,就新建物件存入

if (node == null) else else

}newnode = newnode.next;}}

table[index] = node;

return null;

}

public int getindex(k k, int length)
private void resize() 

}table = newtable;

default_initial_capacity = newtable.length;

}

public v get(k k) 

public nodegetnode(nodenode, k k)

node = node.next;

}return null;

}

public int size()

對於HashMap為什麼要使用陣列加鍊表的個人思考

問題的源頭 hashmap資料結構是?陣列加鍊表,1.8增加了紅黑樹,那麼為什麼?陣列的特點查詢快,增刪慢,鍊錶查詢慢,增刪快,陣列加鍊表是折中方案 其實這種描述並不準確,因為在使用hashmap的時候陣列插入並不慢,而鍊錶增刪快的特點也沒有發揮出來,因為每次put都需要遍歷一遍判斷key值是否相等...

手寫反轉鍊錶

實現過程 line 9 11是將原鍊錶的第乙個節點變成了新鍊錶的最後乙個節點,同時將原鍊錶的第二個節點儲存在cur中 line13 16就是從原鍊錶的第二個節點開始遍歷到最後乙個節點,將所有節點翻轉一遍 以翻轉第二個節點為例 temp cur.next是將cur的下乙個節點儲存在temp中,也就是第...

手寫 LinkedList(雙向鍊錶)

用於 linkedlist 繼承 param public inte ce mylist public class mylinkedlist implements mylist 1.00 將 element 作為最後乙個節點進行連線 param element void linklast e ele...