LinkedHashMap如何在幕后工作?

时间:2012-06-03 12:29:01

标签: java oop dictionary collections hashmap

我阅读了LinkedHashMap并从描述中(尽管非常有趣)我无法理解它是如何实际完成它的工作的。作为旁注,我知道HashMap如何在Java下工作 所以我查看了源代码,仍然无法弄清楚它是如何工作的。在这种情况下,也许我没有在OOP中掌握一些基本内容,所以请耐心等待 总结一下令我困惑的部分如下:
LinkedHashMap将所有来电委托给其父HashMap 在内部,它会覆盖HashMap.Entry以实现各种recordAccessrecordRemoval方法,这些方法似乎实现了LinkedHashMap的逻辑 但实际的Entries位于基类的表中,即HashMap实例化HashMap.Entry而不是LinkedHashMap.Entry的表。
所以我无法弄清楚实际上是如何调用各种recordAccessrecordRemove等 那么有谁能帮我理解这里发生了什么? 我是否认为LinkedHashedMap.Entry是由HashMap创建的表的类型?但是怎么样?

更新
我的问题是如何调用recordAccess。我使用HashMap的衍生版本进行的实验因为盛源路(+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

有何用处

2 个答案:

答案 0 :(得分:4)

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

因为HashMap.HashEntry是包可见性。

PLUS:

我认为困扰你的主要事情是 LinkedHashMap.Entry vs HashMap.Entry 。关键点是LinkedHashMap.Entry 是-a HashMap.Entry。实际上 HashMap.table在LinkedHashMap中存储LinkedHashMap.Entry

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

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

答案 1 :(得分:2)

Ctrl + F在这里是你的朋友,特别是当它允许你一次搜索多个文件时。通过地图的recordAccessput方法在访问/创建的条目上调用get。 (调用位于HashMap.putHashMap.putForNullKeyLinkedHashMap.get。)仅当您使用LinkedHashMap的构造函数时,才会使用布尔参数并将true传递给。这样做的效果是,无论何时触摸地图,触摸的条目都将移动到内部链接列表的前面。

引用文档:

  

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

     

可以重写removeEldestEntry(Map.Entry)方法,以便在将新映射添加到地图时自动删除过时映射的策略。

同样recordRemoval来自HashMap.removeEntryForKeyHashMap.removeMapping

相关问题