/ ** * A dummy entry in the circular linked list of entries in the map. * The first real entry is header.nxt, and the last is header.prv. * If the map is empty, header.nxt == header && header.prv == header. */ transient LinkedEntry<K, V> header;
@OverridevoidpostRemove(HashMapEntry<K, V> e){ // 对header首尾元素的指针重新指向 LinkedEntry<K, V> le = (LinkedEntry<K, V>) e; le.prv.nxt = le.nxt; le.nxt.prv = le.prv; le.nxt = le.prv = null; // Help the GC (for performance) }
访问元素, accessOrder 判断是否调用 makeTail() 方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
@Overridepublic V get(Object key){ ... int hash = secondaryHash(key); HashMapEntry<K, V>[] tab = table; for (HashMapEntry<K, V> e = tab[hash & (tab.length - 1)]; e != null; e = e.next) { K eKey = e.key; if (eKey == key || (e.hash == hash && key.equals(eKey))) { if (accessOrder) makeTail((LinkedEntry<K, V>) e); return e.value; } } returnnull; }
就是这个 makeTail() 方法控制了从 map 中访问数据时 header 的指针 被重置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
@Overridepublic V get(Object key){ / ** * Relinks the given entry to the tail of the list. Under access ordering, * this method is invoked whenever the value of a pre-existing entry is * read by Map.get or modified by Map.put. */ privatevoidmakeTail(LinkedEntry<K, V> e){ // Unlink e e.prv.nxt = e.nxt; e.nxt.prv = e.prv; // Relink e as tail LinkedEntry<K, V> header = this.header; LinkedEntry<K, V> oldTail = header.prv; e.nxt = header; e.prv = oldTail; oldTail.nxt = header.prv = e; modCount++; }