java中LinkedHashMap中的addEntry方法

时间:2016-04-06 02:09:41

标签: java

最近我在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是第二个条目。

1 个答案:

答案 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.beforeX.after中的任何一个或两者都可能是null,那么这个过程会让代码更加尴尬。

我见过使用这两个额外节点的LinkedHashMap版本,以及其他没有版本的版本。在version you're looking at中,第一个和最后一个&#34;虚拟&#34;节点(称为header)实际上是重用的相同对象。