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;
}
}