JDK 版本 11
是这样的,LinkedHashMap 不是用一个双向链表来维护所有插入元素的顺序嘛?
它有一个成员accessOrder
。
final boolean accessOrder;
默认为 false,如果设为 true 的话,每次进行get
操作的时候呢,都会把操作得到的元素移动到链表的末尾。也就是afterNodeAccess
这个方法干的事情
// 访问结点 e 之后,如果结点 e 不在表尾,则会将其移动到表尾(该项功能默认是关闭的,由 accessOrder 负责开启)
void afterNodeAccess(Node<K, V> e) {
LinkedHashMap.Entry<K, V> last;
if(accessOrder && (last = tail) != e) {
//如果能进入到 if 语句,说明 e 不是双向链表的末尾,那么 a 作为 p(e 强转为 Entry 为 p)的后继不可能为 null 对吧?
//如果不能进入 if 语句,说明 e 就是双向链表的末尾,我们不需要做任何操作
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;
}
// 那么既然 a 不可能为 null,这个判断是否多余?这里的 if else 是否多余?
if(a != null) {
a.before = b;
} else {
last = b;
}
if(last == null) {
head = p;
} else {
p.before = last;
last.after = p;
}
tail = p;
++modCount;
}
}
问题来了,如果能够进入大的那个 if 嵌套语句,说明结点 e 不可能是链表末尾结点因为 (last=tail)!=e
那么引用 a 作为 p 的后继节点(p 为 e 强制类型转换后),不可能为 null 对吧?因为只有 e 为链表末尾结点的时候,其后继才会为 null,如果不是链表末尾结点,后继肯定不是 null
那么下面的这个 if else 语句是否多余了? a 一定不会为 null,else 语句貌似永远不能执行?
// 那么既然 a 不可能为 null,这个判断是否多余?这里的 if else 是否多余?
if(a != null) {
a.before = b;
} else {
last = b;
}
然后我自己尝试打断点做实验,发现好像怎么也走不到 else 那个语句...
1
zidian9 2020-05-06 20:00:28 +08:00
多线程情况下可以走到这个里面吧
|
2
alexanderchiu OP @zidian9 有道理...我傻了 可能是别的线程使得 a 变成 null
|
3
beidounanxizi 2020-05-06 21:10:50 +08:00
你好可爱
|