HashMap大家都很了解,是一中比較常用的,也比較好用的集合,但是HashMap有一個順序的問題,就是在對HashMap進行迭代訪問時,添加的順序和訪問的順序可能就不一樣的,這個時候我們可以選擇LinkedHashMap,
LinkedHashMap繼承了HashMap,所以擁有和HashMap一樣的功能;而且在此基礎上有增加了一個雙向鏈表來實現元素迭代的順序,但是肯定會增加時間和空間的消耗,
LinkedHashMap和HashMap一樣,也是非線程安全的
我們還是先來看一個LinkedHashMap的實例,操作數據的方法和HasMap是一樣的,代碼如下:

1 public static void main(String[] args) { 2 LinkedHashMap<String, Object> hasMap = new LinkedHashMap<String, Object>(); 3 hasMap.put("name", "zhangsan"); 4 hasMap.put("age", 20); 5 hasMap.put("addr", "北京市"); 6 hasMap.put(null, null); 7 hasMap.put("info", null); 8 hasMap.put(null, "who"); 9 10 for (Map.Entry<String, Object> entry : hasMap.entrySet()) { 11 System.out.println(entry.getKey() + "=" + entry.getValue()); 12 } 13 }
輸出結果:
name=zhangsan
age=20
addr=北京市
null=who
info=null
根據輸出我們可以得出以下幾個結論:
LinkedHashMap的輸入順序和輸出順序是一致的。
LinkedHashMap允許Key和Value都可以null
LinkedHashMap中添加元素時,如果Key重復,則后添加的會覆蓋前面已經存在的值
LinkedHashMap的具體實現
我們先來看看LinkedHashMap的定義,其中157行有這樣一個定義
1 /**
2 * The head of the doubly linked list. 3 */
4 private transient Entry<K,V> header;
Entry就是LinkedHashMap基本數據結構,Entry是LinkedHashMap定義的一個內部類,繼承了HaspMap.Entry,在此基礎上添加了新添加了兩個屬性。
before、after是用於維護鏈表中Entry的前一個元素和后一個元素。
我們來看一下HaspMap的一個構造函數,
1 public HashMap(int initialCapacity, float loadFactor) { 2 if (initialCapacity < 0) 3 throw new IllegalArgumentException("Illegal initial capacity: " +
4 initialCapacity); 5 if (initialCapacity > MAXIMUM_CAPACITY) 6 initialCapacity = MAXIMUM_CAPACITY; 7 if (loadFactor <= 0 || Float.isNaN(loadFactor)) 8 throw new IllegalArgumentException("Illegal load factor: " +
9 loadFactor); 10
11 this.loadFactor = loadFactor; 12 threshold = initialCapacity; 13 init(); 14 }
此構造函數中最后有一個init的方法,但是此方法在HashMap中沒有實現,LinkedHashMap中重寫了該方法,用來初始化化鏈表。
元素的添加,修改和HashMap就一樣的,雖然LinkedHashMap重寫了addEntry方法,只是增加了刪除eldest entry的功能。
方法removeEldestEntry始終返回false, 所以刪除 eldest entry 實際上不會執行。
總結:從以上可以判斷LinkedHashMap的實現就是 HashMap+LinkedList 的實現方式,用HashMap維護數據結構,用LinkList的方式維護數據插入順序。
利用LinkedHashMap實現LRU算法緩存
轉載自: http://www.cnblogs.com/xrq730/p/5052323.html
解釋一下LRU:LRU即Least Recently Used,最近最少使用,也就是說,當緩存滿了,會優先淘汰那些最近最不常訪問的數據。
要實現這個功能,就是要記錄那些元素被訪問了,訪問的元素應該向前排列,當然這個功能LinkedHashMap已經幫我們實現了,
注意紅框的部分, recordAccess,就是將當前entry移動到鏈表的最前面。
前面說了,LinkedHashMap添加新的元素時會執行刪除eldest entry,雖然LinkedHashMap沒有實現,但是我們可以重寫removeEldestEntry的方法來實現這個功能。
1 public class LRUCache extends LinkedHashMap 2 { 3 public LRUCache(int maxSize) 4 { 5 super(maxSize, 0.75F, true); 6 maxElements = maxSize; 7 } 8
9 protected boolean removeEldestEntry(java.util.Map.Entry eldest) 10 { 11 return size() > maxElements; 12 } 13
14 private static final long serialVersionUID = 1L; 15 protected int maxElements; 16 }
當元素的個數大於指定的值有,就會有原始被刪除掉,也就是鏈表最后的元素。
轉載:http://www.cnblogs.com/xrq730/p/5030920.html