HashMap的原始碼分析

2021-09-28 07:33:00 字數 3009 閱讀 5117

1、底層實現是陣列、鍊錶和紅黑樹

2、key用set存放,所以想要做到key不允許重複,key對應的類需要重寫hashcode和equals方法。允許空鍵和空值(但空鍵只有乙個,且放在第一位)

3、元素是無序的,而且順序會不定時改變

4、插入、獲取的時間複雜度為o(1)(前提是有合適的雜湊函式,讓元素分布於均勻位置)

5、便利整個map時需要的時間與桶(陣列)的長度成正比

7、兩個關鍵因子:初始容量、載入因子

1、陣列:一塊連續的記憶體,可以通過陣列的下標直接對其進行操作

優點:對其尾部進行節點插入簡單容易,可快捷尋找某個位置的元素,通過下標可快速定址。

缺點:查詢元素困難,只能通過遍歷陣列達到查詢目的,插入陣列的非尾部節點十分困難。

2、單鏈表 (由資料節點和next指標節點)head指向頭部,tail指向尾部

優點:next指標指向下乙個資料節點既可插入資料,插入和刪除方便。

缺點:查詢效率低,時間複雜度為o(n)

關於linklist的詳解

**特點:**集陣列、鍊錶和紅黑樹的優點(資料結構)。

原理:

快速定位:其下標的確定pos=key(pos為位置,key為輸入的hash值求模後的結果)。在這裡用較簡單的例子舉例pos=key%size(key為int型別值內容,size為陣列的大小)

1、建構函式:簡單的賦值操作

public hashmap()
static final float default_load_factor = 0.75f;
2、put函式:

傳入引數key和value值,並返回putval()方法的引數數值(由hash(key)方法返回的hash值。初始呼叫時會呼叫resize方法進行初始擴容。

transient node table;
這裡看到table是乙個陣列,初始table為null

static class nodeimplements map.entry
node型別時乙個單鏈表形式(next)指標的存在。

在resize方法中,初始會執行**

newcap = default_initial_capacity;

newthr = (int)(default_load_factor * default_initial_capacity);

其中

static final int default_initial_capacity = 1 << 4; // aka 16
static final float default_load_factor = 0.75f;
所以新容量newcap=16;新閾值newthr=12;

在resize方法中返回的陣列為newtab[16],length為16

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

boolean evict)

所以採用2的冪次的理由是:

1、與記憶體的申請有關,避免記憶體碎片。

2、(n-1)為2的冪次-1,換算成二進位制則會出現後面均為1,提高雜湊度減小雜湊衝突。

static final int hash(object key)
^異或,提高hashcode的雜湊的,避免衝突

原值代表key的hash值,分別檢驗了2組不同key的不異或和異或後和n-1進行與操作的測試,由圖知道,不進行異或的與操作中,兩個不同的key的與操作或會現相同的與結果,二異或後不會,既^異或,提高hashcode的雜湊的,避免衝突。

原始碼借鑑hashmap的解釋

原始碼解釋

1、查詢

首先看**如下:

2、刪除

public v remove(object key) ~
final noderemovenode(int hash, object key, object value,

boolean matchvalue, boolean movable)

p = e;

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

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

(value != null && value.equals(v))))

}return null;

}~

HashMap原始碼分析

public hashmap int initialcapacity,float loadfactor 2 接下來是重要的put方法,put方法用於將鍵值對儲存到map中,讓我們來具體分析一下。public v put k key,v value if key null 若key為null,則將va...

HashMap 原始碼分析

1 getentry object key 方法 final entrygetentry object key return null 根據key的hash值計算出索引,得到table中的位置,然後遍歷table處的鍊錶 for entrye table indexfor hash,table.le...

HashMap原始碼分析

public v put k key,v value if key null return putfornullkey value int hash hash key int i indexfor hash,table.length for entrye table i e null e e.nex...