我正在阅读JDK 11中LinkedHashMap的源代码,发现了一段死代码(我不确定)。
众所周知,LinkedHashMap使用双向链表来维护所有元素的顺序。它有一个名为accessOrder
的成员。
final boolean accessOrder;
默认情况下是 false,但如果设置为 true,则每次运行 get
,它都会将获取到的元素移动到链表的末尾。这就是函数 afterNodeAccess
的作用。
//if accessOrder were set as true, after you visit node e, if e is not the end node of the linked list,
//it will move the node to the end of the linkedlist.
void afterNodeAccess(Node<K, V> e) {
LinkedHashMap.Entry<K, V> last;
if(accessOrder && (last = tail) != e) {
//if enter `if` ,it indicates that e is not the end of the linked list, because (last=tail!=e)
//then `a` as the after node of p(p is e after casting to LinkedHashMap.Entry) is never gonna be null. Only if p is last node of the linked list then a will be null.
LinkedHashMap.Entry<K, V> p = (LinkedHashMap.Entry<K, V>) e, b = p.before, a = p.after;
p.after = null;
if(b == null) {
head = a;
} else {
b.after = a;
}
// Is the if else clasue redundant? `a` must not be null.. the else clase will never be excuted.
if(a != null) {
a.before = b;
} else {
last = b;
}
if(last == null) {
head = p;
} else {
p.before = last;
last.after = p;
}
tail = p;
++modCount;
}
}
这里有一个问题:
假设
(accessOrder && (last = tail) != e
,这意味着 e 不是链表的最后一个节点。如果 e 已经是最后一个节点,我们就不需要做什么了对吧?然后令
a
为 p 的下一个节点(p 是将 LinkedHashMap.Entry 转换后的 e),那么它不能为 null。只有当 p
是最后一个节点时,a
才可能为 null。那么接下来的代码片段有什么用呢?
// Is the if else clasue redundant? `a` must not be null.. the else clase will never be excuted.
if(a != null) {
a.before = b;
} else {
last = b;
}
a
始终 != null
,否则子句 last = b
将永远不会被执行...那么它是死代码吗?
此外,我用 accessorder
设置为 true
进行了一项实验,然后在调试模式下获取了最后一个节点,似乎我永远无法进入上面的 else 子句 last = b
有什么建议吗?
last == null
永远不可能为true
。显然,这只是单纯地复制粘贴了普适的单向链表操作,未针对当前情况进行调整。 - Holger