8

我读到了LinkedHashMap和描述(虽然很有趣),但我无法理解它实际上是如何在幕后工作的。作为旁注,我知道 aHashMap在 Java 中是如何工作的。
所以我查看了源代码,但仍然无法弄清楚它是如何工作的。在这种情况下,也许我没有掌握 OOP 中的一些基本知识,所以请耐心等待。
总结一下让我感到困惑的部分如下:
LinkedHashMap所有调用委托给它的 parent HashMap
在内部,它覆盖了实现似乎实现逻辑的HashMap.Entry各种方法recordAccess, 但实际在基类的表中,即recordRemovalLinkedHashMap
EntriesHashMap它实例化了一个表HashMap.Entry而不是LinkedHashMap.Entry.
所以我无法弄清楚各种recordAccess等等recordRemove实际上是如何被调用的。
那么任何人都可以帮助我了解这里发生了什么吗?
我是否正确地认为这LinkedHashedMap.Entry是由创建的表的类型HashMap?但是怎么做?

更新:
我的问题是如何recordAccess被调用。HashMap由于Shengyuan Lu(+1)的原因, 我使用派生版本进行的实验失败 - 我的错在那里

更新:
我尝试的以下内容与正在做的事情相同(我认为)LinkedHashMap

package delete;  

public class Base<T> {  

    Entry<T>[] table;  
    int idx = 0;  
    @SuppressWarnings("unchecked")  
    public Base(){  
        System.out.println("In base");  
        table = new Entry[10];  
    }

    public void add(T x){  
        table[idx] = new Entry(x);  
        table[idx].doSomething();  
    }  

    static class Entry<T>{  
        T value;  

        Entry(T x){  
            this.value = x;  
            System.out.println("Entry::Base");  
        }

        void doSomething(){  
            System.out.println("In Entry base, doing something");  
        }  
    }  

}  




public class Derived<T> extends Base<T> {  

    static class Entry<T> extends Base.Entry<T>{  

        Entry(T x) {  
            super(x);  
            System.out.println("In Entry derived");  
        }  

        int val;  

        @Override  
        void doSomething() {  
            System.out.println("In Entry derived doing something really smart!");  
        }       
    }  

    /**
     * @param args
     */
    public static void main(String[] args) {  

        Base<String> b = new Derived<String>();  
        b.add("Test string");  

    }  

}  

但它打印:

In base  
Entry::Base     
In Entry base, doing something    

所以派生Entry的永远不会被调用。
我的例子有什么不同吗?我不明白这是如何工作的LinkedHashMap

4

2 回答 2

4

如果您MyLinkedHashMap在 package 下定义java.util,它将编译;)

因为HashMap.HashEntry是包的可见性。

加:

我认为让您感到困惑的主要事情是LinkedHashMap.EntryHashMap.Entry。重点是LinkedHashMap.Entry is-a HashMap.Entry。实际上HashMap.table 将 LinkedHashMap.Entry 存储在 LinkedHashMap 中。

关于recordAccessrecordRemoval,它们都覆盖了 HashMap.Entry 版本。您可以在 LinkedHashMap 和 HashMap 中找到参考。

在此处合并评论:您的示例代码与LinkedHashMap实现不同。LinkedHashMap.addEntry()改为查看。

于 2012-06-03T12:41:39.690 回答
2

Ctrl+F 在这里是您的朋友,尤其是当它允许您一次搜索多个文件时。由地图的和方法recordAccess在访问/创建的条目上调用。(调用在,和中。)仅当您使用 LinkedHashMap 的构造函数时才相关,该构造函数接受一个布尔参数并传递给该参数。这样做的效果是,每当你触摸地图时,被触摸的条目都会被移动到内部链表的前面。putgetHashMap.putHashMap.putForNullKeyLinkedHashMap.gettrue

引用文档:

提供了一个特殊的构造函数来创建链接哈希映射,其迭代顺序是其条目最后一次访问的顺序,从最近最少访问到最近访问(访问顺序)。这种映射非常适合构建 LRU 缓存。调用 put 或 get 方法会导致访问相应的条目(假设它在调用完成后存在)。putAll 方法为指定映射中的每个映射生成一个条目访问,按照指定映射的条目集迭代器提供键值映射的顺序。没有其他方法生成条目访问。特别是,collection-views 上的操作不会影响 backing map 的迭代顺序。

The removeEldestEntry(Map.Entry) method may be overridden to impose a policy for removing stale mappings automatically when new mappings are added to the map.

Similarly recordRemoval is called from HashMap.removeEntryForKey and HashMap.removeMapping.

于 2012-06-03T13:08:41.997 回答