linkedhashmap實現map繼承hashmap,基於map的雜湊表和鏈該列表實現,具有可預知的迭代順序。
linedhashmap維護著乙個執行於所有條目的雙重鍊錶結構,該鍊錶定義了迭代順序,可以是插入或者訪問順序。
linthashmap的節點物件繼承hashmap的節點物件,並增加了前後指標 before after:
/*** linkedhashmap節點物件
*/static
class entryextends hashmap.node
}
accessorder,簡單說就是這個用來控制元素的順序,
accessorder為true: 表示按照訪問的順序來,也就是誰最先訪問,就排在第一位
accessorder為false表示按照存放順序來,就是你put元素的時候的順序。
public linkedhashmap(int initialcapacity, floatloadfactor)
/*** 生成乙個空的linkedhashmap,並指定其容量大小,負載因子使用預設的0.75,
* accessorder為false表示按照存放順序來,就是你put元素的時候的順序
* accessorder為true: 表示按照訪問的順序來,也就是誰最先訪問,就排在第一位
*/public linkedhashmap(int
initialcapacity)
/*** 生成乙個空的hashmap,容量大小使用預設值16,負載因子使用預設值0.75
* 預設將accessorder設為false,按插入順序排序.
*/public
linkedhashmap()
/*** 根據指定的map生成乙個新的hashmap,負載因子使用預設值,初始容量大小為math.max((int) (m.size() / default_load_factor) + 1,default_initial_capacity)
* 預設將accessorder設為false,按插入順序排序.
*/public linkedhashmap(map<? extends k, ? extends v>m)
/*** 生成乙個空的linkedhashmap,並指定其容量大小和負載因子,
* 預設將accessorder設為true,按訪問順序排序
*/public linkedhashmap(int
initialcapacity,
float
loadfactor,
boolean
accessorder)
putmapentries(m,false)呼叫父類hashmap的方法,繼而根據hashmap的put來實現資料的插入:
/*** implements map.putall and map constructor**
@param
m the map
* @param
evict false when initially constructing this map, else
* true (relayed to method afternodeinsertion).
*/final
void putmapentries(map<? extends k, ? extends v> m, boolean
evict)
else
if (s >threshold)
resize();
for (map.entry<? extends k, ? extends v>e : m.entryset())
}}
put呼叫的hashmap的put方法,呼叫兩個空方法,由linkedhashmap實現
publicv put(k key, v value)
final v putval(int hash, k key, v value, booleanonlyifabsent,
boolean
evict)
if (e.hash == hash &&((k = e.key) == key || (key != null &&key.equals(k))))
break
; p =e;}}
if (e != null)
}++modcount;
if (++size >threshold)
resize();
afternodeinsertion(evict);
return
null
; }
在hashmap中紅色部分為空實現:
void afternodeaccess(nodep)void afternodeinsertion(boolean evict)
然後看下linkedhashmap怎麼實現這兩方法:
將當前節點e
移動到雙向鍊錶的尾部。每次linkedhashmap
中有元素被訪問時,就會按照訪問先後來排序,先訪問的在雙向鍊錶中靠前,越後訪問的越接近尾部。當然只有當accessorder
為true
時,才會執行這個操作。
void afternodeaccess(nodee)//尾結點為p
tail =p;
//增加結構性修改數量
++modcount;
}}
afternodeinsertion方法evict
為true
時刪除雙向鍊錶的頭節點
void afternodeinsertion(boolean evict)}
刪除操作呼叫hashmap的remove方法實現元素刪除,remove呼叫removenode,而removenode有乙個方法需要linkedhashmap來實現:
將e
節點從雙向鍊錶中刪除,更改e
前後節點引用關係,使之重新連成完整的雙向鍊錶。
void afternoderemoval(nodee)
e不為空,則獲取e的value值並返回。
publicv get(object key)
accessorder為true,也就是說按照訪問順序獲取內容。
void afternodeaccess(nodee)//尾結點為p
tail =p;
//增加結構性修改數量
++modcount;
}}
linkedhashmap的幾個迭代器:
抽象類linkedha****erator 實現具體刪除,判斷是否存在下個結點,迭代的邏輯。
linkedkeyiterator 繼承自linkedha****erator,實現了iterator介面,對linkedhashmap中的key進行迭代。
linkedvalueiterator 繼承自linkedha****erator,實現了iterator介面,對linkedhashmap中的value進行迭代
linkedentryiterator 繼承自linkedha****erator,實現了iterator介面,對linkedhashmap中的結點進行迭代
abstractclass
linkedha****erator
//是否存在下乙個結點
public
final
boolean
hasnext()
final linkedhashmap.entrynextnode()
//刪除操作
public
final
void
remove()
}final
class linkedkeyiterator extends
linkedha****erator
implements iterator
}final
class linkedvalueiterator extends
linkedha****erator
implements iterator
}final
class linkedentryiterator extends
linkedha****erator
implements iterator>
}
AbstractCollection原始碼分析
abstractcollection抽象類提供了collection的骨架實現,collection分析請看 這裡直接看它的 是如何實現的.public abstract iterator iterator 該方法沒有實現.public abstract int size 該方法沒有實現.publi...
ThreadPoolExecutor原始碼閱讀
執行緒池解決兩個問題 一是復用執行緒,減少建立銷毀執行緒帶來系統開銷 二是限定系統資源使用邊界,避免大量執行緒消耗盡系統記憶體 適用於互不依賴,執行時間短,不需要對執行緒控制操作的執行緒 新增任務時,1.若執行緒數量小於corepoolsize,則新增執行緒執行任務 2.若執行緒數量大於等於core...
OrangePi One Android 原始碼編譯
一 系統環境搭建參照 二 lichee原始碼編譯 1.檢視help build.sh h2.配置核心 cd linux 3.4 make arch arm menuconfig 進入配置頁面,上下移動列表,空格是選擇列表,左右移動選擇退出選項 3.首次編譯執行清除 在 lichee linux3.4...