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 你好可爱 |