最近我在java中读了LinkedHashmap
的源代码,我知道链接的hashmap使用双重链接来恢复条目。当addEntry
时,它将删除列表中最长的键,但是当我读取代码时,我遇到了一些问题
426 addEntry(int hash, K key, V value, int bucketIndex) {
427 super.addEntry(hash, key, value, bucketIndex);
428
429 // Remove eldest entry if instructed
430 Entry<K,V> eldest = header.after;
431 if (removeEldestEntry(eldest)) {
432 removeEntryForKey(eldest.key);
433 }
434 }
在第430行,eldest = header.after
,但我认为列表的末尾不是header.after
,因为header.after
是第二个条目。
答案 0 :(得分:2)
LinkedHashMap
的代码随着时间的推移而发生了变化,这对于Android来说是完全不同的代码,所以我不确定是哪个版本。但是,在我看来,拥有&#34; dummy&#34;第一个节点之前和最后一个节点之后的节点(这样即使空的LinkedHashMap
也有2个节点)。这样,您可以通过获取X
之前和之后的节点从地图中删除节点X
:
X.before -> X -> X.after
并将X.before
后的新节点设为X.after
,将X.after
之前的新节点设为X.before
。
X.before ------> X.after (X has gone.)
此代码可以简单地为:
X.before.after = X.after;
X.after.before = X.before;
如果您没有虚拟节点,X.before
或X.after
中的任何一个或两者都可能是null
,那么这个过程会让代码更加尴尬。
我见过使用这两个额外节点的LinkedHashMap
版本,以及其他没有版本的版本。在version you're looking at中,第一个和最后一个&#34;虚拟&#34;节点(称为header
)实际上是重用的相同对象。