我阅读了LinkedHashMap并从描述中(尽管非常有趣)我无法理解它是如何实际完成它的工作的。作为旁注,我知道HashMap
如何在Java下工作
所以我查看了源代码,仍然无法弄清楚它是如何工作的。在这种情况下,也许我没有在OOP中掌握一些基本内容,所以请耐心等待
总结一下令我困惑的部分如下:
LinkedHashMap
将所有来电委托给其父HashMap
在内部,它会覆盖HashMap.Entry
以实现各种recordAccess
和recordRemoval
方法,这些方法似乎实现了LinkedHashMap
的逻辑
但实际的Entries
位于基类的表中,即HashMap
实例化HashMap.Entry
而不是LinkedHashMap.Entry
的表。
所以我无法弄清楚实际上是如何调用各种recordAccess
和recordRemove
等
那么有谁能帮我理解这里发生了什么?
我是否认为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
答案 0 :(得分:4)
如果您在包MyLinkedHashMap
下定义java.util
,它将编译;)
因为HashMap.HashEntry
是包可见性。
PLUS:
我认为困扰你的主要事情是 LinkedHashMap.Entry vs HashMap.Entry 。关键点是LinkedHashMap.Entry 是-a HashMap.Entry。实际上 HashMap.table在LinkedHashMap中存储LinkedHashMap.Entry 。
关于recordAccess
和recordRemoval
,它们都覆盖了HashMap.Entry版本。你可以在LinkedHashMap和HashMap中找到引用。
此处合并评论:您的示例代码与LinkedHashMap
实施不同。请改为LinkedHashMap.addEntry()
。
答案 1 :(得分:2)
Ctrl + F在这里是你的朋友,特别是当它允许你一次搜索多个文件时。通过地图的recordAccess
和put
方法在访问/创建的条目上调用get
。 (调用位于HashMap.put
,HashMap.putForNullKey
和LinkedHashMap.get
。)仅当您使用LinkedHashMap的构造函数时,才会使用布尔参数并将true
传递给。这样做的效果是,无论何时触摸地图,触摸的条目都将移动到内部链接列表的前面。
引用文档:
提供了一个特殊的构造函数来创建链接的哈希映射,其迭代顺序是上次访问其条目的顺序,从最近访问到最近访问(访问顺序)。这种地图非常适合构建LRU缓存。调用put或get方法会导致访问相应的条目(假设它在调用完成后存在)。 putAll方法为指定映射中的每个映射生成一个条目访问,按照指定映射的条目集迭代器提供键 - 值映射的顺序。没有其他方法可以生成入口访问。特别是,对集合视图的操作不会影响后备映射的迭代顺序。
可以重写removeEldestEntry(Map.Entry)方法,以便在将新映射添加到地图时自动删除过时映射的策略。
同样recordRemoval
来自HashMap.removeEntryForKey
和HashMap.removeMapping
。