1、開始 public class LinkedHashMap<K,V> extends HashMap<K,V> implements Map<K,V> 繼承了類HashMap,實現了Map接口 2、屬性 //雙向鏈表,用於記錄全部的元素 private transient Entry<K,V> header; //遍歷順序【訪問順序或插入順序】,默認插入順序 private final boolean accessOrder; 3、雙向鏈表 private static class Entry<K,V> extends HashMap.Entry<K,V> { //雙向鏈表中的上一個節點before和下一個節點after Entry<K,V> before, after; Entry(int hash, K key, V value, HashMap.Entry<K,V> next) { super(hash, key, value, next); } //從雙向鏈表中刪除元素 private void remove() { //改變當前節點的先後兩個節點的引用關係,若當前節點沒有被引用,則才能夠被GC回收 //將前一個節點的after指向後一個節點 before.after = after; //將後一個節點的before指向前一個節點 after.before = before; } //將當前節點插入到指定節點的鏈表中,即指定節點的前面 private void addBefore(Entry<K,V> existingEntry) { //指定當前節點與先後節點的引用關係 //將當前節點的後一個節點指向指定節點 after = existingEntry; //將當前節點的前一個節點指向指定節點的前一個節點 before = existingEntry.before; //指定先後節點與當前節點的引用關係 //當前節點的前一個節點的後一個節點就是當前節點 before.after = this; //當前節點的後一個節點的前一個節點就是當前節點 after.before = this; } //查詢或修改元素時調用 void recordAccess(HashMap<K,V> m) { LinkedHashMap<K,V> lm = (LinkedHashMap<K,V>)m; if (lm.accessOrder) { //當時按訪問順序時,即最近較少使用順序LRU lm.modCount++; //刪除當前節點 remove(); //噹噹前節點添加到鏈表尾部 addBefore(lm.header); } } //刪除元素時調用 void recordRemoval(HashMap<K,V> m) { remove(); } } 4、構造器 //指定容量和加載因子,遍歷順序爲插入順序 public LinkedHashMap(int initialCapacity, float loadFactor) { super(initialCapacity, loadFactor); accessOrder = false; } //默認加載因子,遍歷順序爲插入順序 public LinkedHashMap(int initialCapacity) { super(initialCapacity); accessOrder = false; } //默認初始化容量和加載因子,遍歷順序爲插入順序 public LinkedHashMap() { super(); accessOrder = false; } //添加元素用於初始化,遍歷順序爲插入順序 public LinkedHashMap(Map<? extends K, ? extends V> m) { super(m); accessOrder = false; } //指定容量和加載因子,以及遍歷順序 public LinkedHashMap(int initialCapacity, float loadFactor, boolean accessOrder) { super(initialCapacity, loadFactor); this.accessOrder = accessOrder; } //構造對象時,初始化雙向鏈表 @Override void init() { //初始化頭節點 header = new Entry<>(-1, null, null, null); //頭結點便是其自身的前一個也是後一個 header.before = header.after = header; } 5、添加 //添加時,重寫了HashMap的此方法 void addEntry(int hash, K key, V value, int bucketIndex) { super.addEntry(hash, key, value, bucketIndex); //頭結點的第一個節點 Entry<K,V> eldest = header.after; if (removeEldestEntry(eldest)) { //刪除第一個節點 removeEntryForKey(eldest.key); } } //新增節點 void createEntry(int hash, K key, V value, int bucketIndex) { //獲取老鏈表 HashMap.Entry<K,V> old = table[bucketIndex]; //新增節點 Entry<K,V> e = new Entry<>(hash, key, value, old); //添加到數組中 table[bucketIndex] = e; //當前節點添加到頭結點尾部,添加使用前插法 e.addBefore(header); //計數 size++; } //是否刪除第一個節點,即老的節點 protected boolean removeEldestEntry(Map.Entry<K,V> eldest) { return false; } 6、查找 public V get(Object key) { Entry<K,V> e = (Entry<K,V>)getEntry(key); if (e == null) return null; //記錄查找的元素,用於根據訪問的順序時,維護雙向鏈表 e.recordAccess(this); return e.value; } 參考資料: http://www.cnblogs.com/tstd/p/5059589.html