資料結構 Map jdk1 8

2021-08-25 14:04:24 字數 2406 閱讀 2189

陣列擴容

迭代器

預設陣列容量16,擴容0.75,轉紅黑樹8,轉回鍊錶6
資料結構終極目標:查的快改的也快

查詢迅速:陣列

增刪迅速:鍊錶

jdk1.8之前就是使用陣列+鍊錶的結構綜合兩者的優勢

由於鍊錶查詢慢,o(n),jdk1.8之後,對鍊錶進行了優化,當滿足某些條件時,整個鍊錶轉為紅黑樹;

下標的確認

//方式一:取模   私以為這種方式可讀性更改 沒什麼限制

int index = hashcode % tab.cap ;//通過陣列下標取模保證通過hashcode一定是在陣列下標上

//方式二:位運算 cpu操作速度更快, 有限制 需要陣列容量是2的次方 才能保證tab.cao-1 = 011111111

//進一步保證計算結果是hashcode的

int index = hashcode & (tab.cap -1);

//101110001110101110 1001 &0 1111 = 1001 = 9

//方式二 要保證tab.cap-1 的結果時01111111才可以保證最終結果的值都**於原始的hashcode,

// 如果不是2的n次方,那位與運算時必定有些值是得不到的,不能均勻

這也是為什麼資料初始容量要求是2的n次方了(比如16)

在使用方式二的運算,計算下標時只會用到原hashcode的低位,為了保證衝突更少,通過亦或運算將高16位與低位結合保證資料衝突的概率更低

當然如果下標已有值,即產生了hash衝突

hash衝突

既然是hashmap,那hash衝突是無法避免的,hashmap當發現同一位置有值時,就往鍊錶下走,而如果插入後鍊錶長度達到8,則轉紅黑樹

為什麼轉紅黑樹要求鍊錶長度是8呢?

個人認為,優化的目標是為了提高查詢效率,而轉換成紅黑樹的過程也是需要cpu計算的,所以這個轉換的條件需要提高的查詢效率能抵消轉換的消耗,

習慣性的以2的次方來算,o(n) vs o(logn),當達到8次是,鍊錶查詢0~8次,紅黑樹0~3次,這個查詢效率的增加認為已經可以抵消了

部分原始碼

public v put(k key, v value) 

static

final

int hash(object key)

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

boolean evict)

if (e.hash == hash &&

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

break;

p = e;}}

//hash衝突後且equals的情況下 替換原來的值

v oldvalue = e.value;

if (!onlyifabsent || oldvalue == null)

e.value = value;

afternodeaccess(e);

return oldvalue;}}

//操作次數+1 用於迭代器的快速失效 即迭代器/foreach遍歷期間如果有其他執行緒操作 則這個值會變,變了就fail-fast 拋異常

++modcount;

if (++size > threshold)//16*0.75=12

resize();//擴容 翻倍 擴容後不行則擴到需要的容量

afternodeinsertion(evict);

return

null;

}

擴容後重新計算hash

a.私以為:擴容後直接遍歷久資料,呼叫put方法 重新計算hash 下標, 則**復用

這也可以滿足要求

b.原始碼: 分陣列/鍊錶/紅黑樹 ,對三種不同結構直接採用不同演算法,效率更快

hashmap中的迭代器和foreach個人感覺沒什麼區別
public

void

foreach(biconsumer<? super k, ? super v> action)

//每次迭代 都確認modcount有沒有被操作,即map有沒有被改,有則fail-fast

if (modcount != mc)

throw

new concurrentmodificationexception();

}}

資料結構1 8 對映

1 對映 顧名思義,就是乙個值對應到另外乙個值,屬於一對一形式,對映在生活中也有很多體現,類似與身份證號和人屬於一對一的對映,車子和車牌也是對映,而在開發中,比如 資料庫id對應一條資料,也是屬於對映。官方一點的釋義 儲存資料結構,根據key對應value 寫乙個基於鍊錶的對映來練習一下原理 pac...

C 資料結構 18 堆

堆的實現通過構造二叉堆 binary heap 實為二叉樹的一種 由於其應用的普遍性,當不加限定時,均指該資料結構的這種實現。這種資料結構具有以下性質。任意節點小於 或大於 它的所有後裔,最小元 或最大元 在堆的根上 堆序性 堆總是一棵完全樹。即除了最底層,其他層的節點都被元素填滿,且最底層盡可能地...

資料結構18 資料結構中的字串

資料結構中的字串 字串bf演算法 普通模式匹配演算法 資料結構中提到的串,即字串,由 n 個字元組成的乙個整體 n 0 這 n 個字元可以由字母 數字或者其他字元組成。例如,s beijing s 代表這個串的串名,beijing 是串的值。雙引號不是串的值,作用只是為了將串和其他結構區分開。特殊的...