LinkedHashMap 是hashMap的子类.. 可以维持一个插入的顺序..如果 accessOrder为true的话则最后访问的在最后面..
LinkedHashMap 中维持了一个双向的链表
/**
* The head (eldest) of the doubly linked list.
*/
// 头位置
transient LinkedHashMap.Entry<K,V> head;
/**
* The tail (youngest) of the doubly linked list.
*/
// 尾位置
transient LinkedHashMap.Entry<K,V> tail;
每次在新建一个node的时候会将新插入的元素移动到双向聊表的尾巴处 putVal中的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);
linkNodeLast(p);
return 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;
}
}
remove的时候会调用 来删除掉双向链表中的节点..
void afterNodeRemoval(Node<K,V> e) { // unlink
LinkedHashMap.Entry<K,V> p =
(LinkedHashMap.Entry<K,V>)e, b = p.before, a = p.after;
p.before = p.after = null;
if (b == null)
head = a;
else
b.after = a;
if (a == null)
tail = b;
else
a.before = b;
}
在获取节点的时候如果是 assessOrder为true 则会修改双向链表中的位置 这里的modeCount是在++的迭代的时候可能会出现快速失败的异常
void afterNodeAccess(Node<K,V> e) { // move node to last
LinkedHashMap.Entry<K,V> last;
// 如果不是最后一个
if (accessOrder && (last = tail) != e) {
// 取到前后节点
LinkedHashMap.Entry<K,V> p =
(LinkedHashMap.Entry<K,V>)e, b = p.before, a = p.after;
// 因为要设置成最后一个after是没有的
p.after = null;
// p就是第一个没有before
if (b == null)
head = a; // 则头设置成下一个元素
else
b.after = a; // before 设置成after 把p的关联断开
if (a != null) // 有下一个
a.before = b; // 下一个与p的关联断开与b建立关联
else
last = b;
if (last == null)
head = p;
else {
p.before = last;
last.after = p;
}
tail = p;
++modCount;
}
}