JDK版本为1.8.0_271,LinkedHashMap继承了HashMap,LinkedHashMap在HashMap的基础上维护了一个双向链表,实现了可以根据插入顺序/访问顺序(accessOrder=false/true)访问Map集合。
关于HashMap的原理可以参考HashMap部分底层源码解析
部分属性:
/*** 双向链表头节点*/transient LinkedHashMap.Entry<K,V> head;/*** 双向链表尾节点*/transient LinkedHashMap.Entry<K,V> tail;/*** 默认为accessOrder=false,表示按照插入顺序迭代* accessOrder=true,表示按照访问顺序迭代*/final boolean accessOrder;
内部定义的Entry如下:
static class Entry<K,V> extends HashMap.Node<K,V> {Entry<K,V> before, after; // Node节点的前后指针Entry(int hash, K key, V value, Node<K,V> next) {super(hash, key, value, next);}
}
LinkedHashMap重写了HashMap中的newNode()方法:
Node<K,V> newNode(int hash, K key, V value, Node<K,V> e) { LinkedHashMap.Entry<K,V> p = new LinkedHashMap.Entry<K,V>(hash, key, value, e); // 新增的键值对p也要尾插法挂到双向链表 linkNodeLast(p); return p;
}
TreeNode<K,V> newTreeNode(int hash, K key, V value, Node<K,V> next) {TreeNode<K,V> p = new TreeNode<K,V>(hash, key, value, next);linkNodeLast(p); // 新增的键值对p也要尾插法挂到双向链表 return p;
}// 键值对p要尾插法挂到双向链表
private void linkNodeLast(LinkedHashMap.Entry<K,V> p) {LinkedHashMap.Entry<K,V> last = tail;tail = p;// 尾插法挂载节点到双向链表if (last == null)head = p;else {p.before = last;last.after = p;}
}