與hashmap的異同:同樣是基於雜湊表實現,區別是,linkedhashmap內部多了乙個雙向迴圈鍊錶的維護,該鍊錶是有序的,可以按元素插入順序或元素最近訪問順序(lru)排列,
簡單地說:linkedhashmap=雜湊表+迴圈雙向鍊錶
首先,hashmap的構造方法都要呼叫乙個方法 init(),而linkedhashmap對這個方法進行了重寫:
public
hashmap(int initialcapacity, float loadfactor)
@override
void init()
如果已經熟悉過hashmap,那麼你一定可以發現,這裡的entry<>已經和hashmap中的entry內部類不一樣了,所以,linkedhashmap重寫了hashmap中最基本的單元entry:
/**
* linkedhashmap entry.
*/private static class
entry
extends
hashmap.entry
private void remove()
private void addbefore(entryexistingentry)
void recordaccess(hashmapm)
}void recordremoval(hashmapm)
}
看到這段內部類的**,我們可以總結出兩個重要的特性:
(1)這裡的 before 和 after 是增加的。此處的entry它繼承了hashmap.entry,所以它的成員變數有:
hash值(這個容易被忽略)
key 和 value 兩個變數
用於維護雜湊表的 next
用於維護雙向迴圈鍊錶的 before 和 after
(2)linkedhashmap中依然在使用 【桶+鍊錶】 的典型雜湊表結構。這一點從它復用的hashmap中的**可以看出。所以,它依然會有resize,使用的是鍊錶來維護順序,所以,resize並不會破壞這個順序的維護。
private final boolean accessorder;
accessorder:true則按照lru演算法迭代整個linkedhashmap,false則按照元素的插入順序迭代!
最後兩個圖是精髓,訪問就是先刪除後新增到尾部。
迴圈雙向鍊錶的頭部存放的是最久訪問的節點或最先插入的節點,尾部為最近訪問的或最近插入的節點
如果上圖太簡單的話,下面有個例子還是不錯的:
public static void main(string args)
system.out
.println("**** 初始順序:****");
for (map.entry
entry : lmap.entryset())
// 依次訪問8,1,4,7,3
lmap.get(8);
lmap.get(1);
lmap.get(4);
lmap.get(7);
lmap.get(3);
system.out
.println("\n\n**** 訪問過後的順序:****");
for (map.entry
entry : lmap.entryset())
// put 新值
lmap.put(11, "@" + 11);
lmap.put(12, "@" + 12);
lmap.put(13, "@" + 13);
system.out
.println("\n\n**** 插入新k-v後的順序:****");
for (map.entry
entry : lmap.entryset())
// put 舊值
lmap.put(0, "new" + 0);
lmap.put(2, "new" + 2);
lmap.put(4, "new" + 4);
system.out
.println("\n\n**** 插入舊k後的順序:****");
for (map.entry
entry : lmap.entryset())
}
output:
**** 初始順序:****
@0@1
@2@3
@4@5
@6@7
@8@9
**** 訪問過後的順序:****
@0@2
@5@6
@9@8
@1@4
@7@3
**** 插入新k-v後的順序:****
@0@2
@5@6
@9@8
@1@4
@7@3
@11@12
@13
**** 插入舊k後的順序:****
@5@6
@9@8
@1@7
@3@11
@12@13 new0 new2 new4
實現的原理就是,每次get的時候,將這個元素移到佇列的末尾,從而,最不常訪問的元素在佇列的首部。
參考資料:
Java知識學習
讀取檔案裡面的內容,直接讀取不就得了,但是我看到很多人都要乙個位元組陣列,例如 byte b new byte 1024 然後再讀取 b裡面的內容,像下面這樣 fileinputstream in new fileinputstream e lyrics.txt byte b new byte 10...
java 知識蒐集
我們都知道instanceof測試乙個例項是不是乙個類的例項。那麼如果你認為乙個dog 的dog instanceof object 會返回假,那你就大錯特錯了。對於所有的父類 super 類,instanceof 測試都會返回真。我們來看這個例子 class base class ext1 ext...
java知識總結
包的訪問控制 子類 同個包內 不同包內 public y y y protect y y n private n n n i o和流 四個抽象類 讀寫位元組 inputstream outputstream 讀寫unicode字元 reader writer iterator arraylist v...