陣列擴容
迭代器
預設陣列容量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 是串的值。雙引號不是串的值,作用只是為了將串和其他結構區分開。特殊的...