HashMap實現方法概述

2021-09-24 18:50:53 字數 1477 閱讀 8663

hashmap是採用陣列( table ) + 鍊錶儲存的,table陣列的每個元素都是乙個鍊錶。 鍊錶的核心資料結構是node:

static class nodeimplements map.entry
即儲存乙個key-value鍵值對,外加hash值和其指向的節點的位址引用。

當put(key,value)時,過程如下:

根據key值計算乙個hash值,然後根據hash值和table的length計算該key所在的桶的索引(即table[i])

在table[i] 這個鍊錶中依次查詢key,如果能找到,就用新value替換掉之前的老value; 如果找不到,就在此鍊錶中新增乙個節點,用來儲存這個key-value鍵值對;

新增節點時,new 乙個node1並令其儲存table[i],然後再new乙個node2,令node2的next指向node1, 再令table[i] = node2,這樣就把新增的node2插入到了之前的table[i]鍊錶的第乙個位置;

插入完成後,當前的hashmap中包含的key-value總數(size)增加了1,這時要檢查是否超過了我們設定的閾值threshold,如果超過了,就要對hashmap進行擴容,並將資料從老的hashmap遷移到新的hashmap中去

擴容(resize)時,遍歷老的table,在其中遍歷每個table[i]鍊錶,根據hash值和新容量對每個node計算其新的桶索引(newtable[i])。將node插入到新的桶的最前邊去。

至此,put過程結束。

而在多執行緒的情況下,當執行到步驟5時,由於多個執行緒都要不斷地將node插入到桶的最前面去,在這個過程中可能會形成環形鏈結。

參考文章: 寫的太好了,必須推薦。以上只是對文章中的思想進行了總結。

hashtable是通過將put,get等方法加上synchronized關鍵字(同步鎖),每次只能有乙個執行緒進行存或取。以此避免發生執行緒不安全問題,但這種方式必然會以犧牲效率為代價。

concurrenthashmap的實現與hashtable有所不同,它是通過在table之外再加一層segment
引用(

當每次進行put和get操作時,不必對整個map都加鎖,只需要對table所在的segment加上同步鎖就可以了。另外rehash也是在單個segment中進行,成本較低。這樣既避免了執行緒安全問題,又保證了高併發的訪問效率。

參考文章:

treemap:除了實現map介面之外還實現了sortedmap介面,集合中的對映關係有一定的順序(按照鍵公升序、降序或自定義順序),但效能較差,執行緒不安全。

linkedhashmap:它是hashmap的子類,用雙向鍊錶儲存,遍歷順序與插入時的順序一樣。它在resize時不用對key-value重新排序,但它是用鍊錶維護內部順序,增加了空間開銷的同時,也因此遍歷的效能較高。它也是執行緒不安全的。

HashMap遍歷方法和實現原理分析

public class circlemap 該方法僅用於新增乙個key value隊 void addentry int hash,k key,v value,int bucketindex 獲取指定 bucketindex 索引處的 entry entrye table bucketindex ...

hashmap實現機制

int uint key.gethashcode 0x8ffffff 具體多少忘記了,總之就是把它弄成正數 int index uint map.length 把value放到那個 index位置。下次訪問時再通過 key的hashcode 0x8fffff 再 map.length 就知道valu...

HashMap實現原理

hashmap 的get 方法 呼叫get方法返回entry public v get object key getentry方法 final entrygetentry object key 對key int hash key null 0 hash key for entrye table in...