- 继承于HashMap,定义了新的内部类Entry用于实现双向链表保存记录的插入或访问顺序;
- accessOrder用于指示链表保存记录采用的顺序,true为访问顺序,false为插入顺序;
- 加入新的记录时需要更新链表,访问记录时需要更新链表(更具accessOrder值判断是否实际更新);
- removeEldestEntry方法在LinkedHashMap用于表示缓存时有用,通过重载该方法(修改更新链表的逻辑以及返回值),删除有限容量下缓存中的最旧记录;
1 public class MyLinkedHashMap<K, V> extends MyHashMap<K, V> { 2 private boolean accessOrder; 3 4 private Entry<K, V> header; 5 6 public V get(K k) { 7 Entry<K, V> e = (Entry<K, V>) getEntry(k); 8 if (e == null) { 9 return null; 10 } 11 e.recordAccess(this); 12 return e.value; 13 } 14 15 @Override 16 void addEntry(K k, V v, int index) { 17 MyHashMap.Entry<K, V> old = table[index]; 18 Entry<K, V> e = new Entry<K, V>(k, v, old); 19 table[index] = e; 20 e.addBefore(header); 21 size++; 22 Entry<K, V> eldest = header.after; 23 /** 24 * 如果用於表示LRU算法的缓存,需覆盖removeEldestEntry,删除最旧条目同时返回true 25 */ 26 if (removeEldestEntry(eldest)) { 27 removeEntryForKey(eldest.key); 28 } else { 29 if (size >= threshold) { 30 resize(2 * table.length); 31 } 32 } 33 } 34 35 boolean removeEldestEntry(Entry<K, V> e) { 36 return false; 37 } 38 39 private static class Entry<K, V> extends MyHashMap.Entry<K, V> { 40 Entry<K, V> before, after; 41 42 public Entry(K k, V v, MyHashMap.Entry<K, V> n) { 43 super(k, v, n); 44 // TODO Auto-generated constructor stub 45 } 46 47 private void remove() { 48 before.after = after; 49 after.before = before; 50 } 51 52 private void addBefore(Entry<K, V> existingEntry) { 53 after = existingEntry; 54 before = existingEntry.before; 55 after.before = this; 56 before.after = this; 57 } 58 59 void recordAccess(MyHashMap<K, V> m) { 60 MyLinkedHashMap<K, V> lm = (MyLinkedHashMap<K, V>) m; 61 if (lm.accessOrder) { 62 remove(); 63 addBefore(lm.header); 64 } 65 } 66 67 } 68 69 }