在緩存中查找一個數據java
從緩存中刪除一個數據算法
往緩存中添加一個數據緩存
若是你熟悉 Java,那你幾乎每天會用到這個容器。咱們以前講HashMap 底層是經過散列表這種數據結構實現的。而 LinkedHashMap 前面比 HashMap 多了一Linked」,數據結構
這裏的「Linked」是否是說,LinkedHashMap 是一個經過鏈表法解決散列衝突的散列表呢?函數
實際上,LinkedHashMap 並無這麼簡單,其中的「Linked」也並不只僅表明它是經過鏈表法解決散列衝突的。關於這一點,在我是初學者的時候,也誤解了好久3d
咱們先來看一段代碼。你以爲這段代碼會以什麼樣的順序打印 3,1,5,2 這幾個 key 呢?緣由又是什麼呢?blog
HashMap<Integer, Integer> m = new LinkedHashMap<>(); m.put(3, 11); m.put(1, 12); m.put(5, 23); m.put(2, 22); for (Map.Entry e : m.entrySet()) { System.out.println(e.getKey()); }
我先告訴你答案,上面的代碼 會按照數據插入的順序依次來打印,也就是說,打印順序就是
,你有沒有以爲奇怪?散列表中的數據是通過散列幻術打亂以後無規律存儲的,
這裏是如何實現按照數據的插入順序來遍歷數據,你能夠看下面這段代碼:排序
你可能已經猜到,也是經過散列表和鏈表組合在一塊兒實現的,實際上,它不只支持按照插入順序遍歷數據
還支持按照問順序來遍歷數據,你能夠看下這段代碼get
// 10 是初始大小,0.75 是裝載因子,true 是表示按照訪問時間排序 HashMap<Integer, Integer> m = new LinkedHashMap<>(10, 0.75f, true); m.put(3, 11); m.put(1, 12); m.put(5, 23); m.put(2, 22); m.put(3, 26); m.get(5); for (Map.Entry e : m.entrySet()) { System.out.println(e.getKey()); }
這段代碼的結果是1,2,3,5我來抉剔分析一下,爲何這段代碼會按照這樣的順序來打印class
每次調用put()函數往 中添加數據的時候,都會將數據添加到鏈表的尾部,因此,在前四個操做完成以後,鏈表中的數據是下面這樣的
在第 8 行代碼中,再次將鍵值爲 3 的數據放入到 LinkedHashMap 的時候,會先查找這個鍵值是否已經有了,
而後,再將已經存在的 (3,11) 刪除,而且將新的 (3,26) 放到鏈表的尾部。因此,這個時候鏈表中的數據就是下面這樣:
當第 9 行代碼訪問到 key 爲 5 的數據的時候,咱們將被訪問到的數據移動到鏈表的尾部。因此,第 9 行代碼以後,鏈表中的數據是下面這樣:
因此,最後打印出來的數據是1,2,3,5從上面的分析,你有沒有發現,按照訪問時間排序的,自己就是一個支持淘汰策略的緩存系統?實際上,
他們兩個的實現原理也是如出一轍的,我也就再也不囉嗦了
我如今來總結一下,實際上,LinkedHashMap 是經過雙向鏈表和散列表這兩種數據結構組合實現的LinkedHashMap 中的「Linked」其實是指的雙向鏈表,並不是指用鏈表法解決散列衝突