本博客是基于Java8的,预期是想将所有函数都看一遍:
这是查看source时候的第一个代码块:是一个构造函数
private void linkNodeLast(LinkedHashMap.Entry<K,V> p) {
//保存之前的链尾
LinkedHashMap.Entry<K,V> last = tail;
//将参数值赋值给链尾,此时last还是指向原先的链尾
//有个疑问:为什么要进行赋值,而不是直接采用下面自己写的方式
//原因在于:Java存取堆栈中的数据比存取成员变量和全局变量的操作要少,因而性能更高
tail = p;
if (last == null)
head = p;
else {
p.before = last;
last.after = p;
}
//自己写的
if(tail==null){
head=p;
}else{
p.before=tail;
tail.after=p;
}
}
第二个代码块:
// 将src node连接至dst末尾
private void transferLinks(LinkedHashMap.Entry<K,V> src,
LinkedHashMap.Entry<K,V> dst) {
LinkedHashMap.Entry<K,V> b = dst.before = src.before;
LinkedHashMap.Entry<K,V> a = dst.after = src.after;
//确保无论是src或者dst都有前节点,意味着如果不为空,说明这个节点是挂在某个串下的,则继续讲这个节点挂在这个串下
if (b == null)
head = dst;
else
b.after = dst;
//判断无论是src或者是ds是否后面还连着一个串,如果连着则继续连着
if (a == null)
tail = dst;
else
a.before = dst;
//这种编码形式很棒啊,不采用if判断,而是直接连等代替
}
之后的是一些静态内部类的构造函数,跳过
替换节点函数:
Node<K,V> replacementNode(Node<K,V> p, Node<K,V> next) {
//父类想向转为子类
LinkedHashMap.Entry<K,V> q = (LinkedHashMap.Entry<K,V>)p;
LinkedHashMap.Entry<K,V> t =
new LinkedHashMap.Entry<K,V>(q.hash, q.key, q.value, next);
//相连
transferLinks(q, t);
return t;
}
节点移除函数
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;
//没有前驱节点,说明这个节点不是挂在某个串上的,说明是头节点,则将head指向头结点的下一个节点
if (b == null)
head = a;
else
//指向下一个节点,防止断链
b.after = a;
if (a == null)
//说明是尾节点,则将尾节点指向前一个节点
tail = b;
else
//否则相连
a.before = b;
}
判断入队之后是否需要出队:
void afterNodeInsertion(boolean evict) { // possibly remove eldest
LinkedHashMap.Entry<K,V> first;
if (evict && (first = head) != null && removeEldestEntry(first)) {
K key = first.key;
removeNode(hash(key), key, null, false, true);
}
}
2018-10-10 23:13 更:
LinkedHashMap与HashMap的区别在于LinkedHashMap是一个双向链表,看源码的时候有点奇怪,put的时候并没有看到如何维护的啊,head,tail哪里用到了,后来发现原来是重写了:newNode方法:
这个方法将tail节点和新增的节点拉钩,,这样就维护好了一个双向队列
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;
}
}
借用一下别人的图,有这张图大家应该瞬间明了了:
此图转自:https://blog.csdn.net/u012403290/article/details/70143443?locationNum=14&fps=1 尊重原创。