我对如何使用LinkedHashMap(How would you implement an LRU cache in Java 6?)构建LRU缓存感到有点困惑,我想确保我理解它在幕后的内部工作原理。
假设我定义了一个类LRUMap,它扩展LinkedHashMap并覆盖removeEldestEntry(final Map.Entry<A, B> eldest)
就像它一样。
然后我构建数据结构并在地图中插入4个项目
LRUMap<String,String> map = new LRUMap<String,String>(3); //capacity 3
map.put("a", "a");
map.put("b", "b");
map.put("c", "c");
map.put("d", "d");
并且inte LinkedHashMap
使用名为Entry object
的{{1}}作为起始节点来链接您添加到地图中的所有项目。所以在这种情况下它将是
header
标题Entry对象既是header.before = header.after = header,也是双链表的起点和终点。
让我们说地图达到我想要的最大条目数(3项),并且来自
[header] -> ["a"] -> ["b"] -> ["c"] -> ["d"] -> [header]
这是否意味着它首先会删除[“a”]?
当我们调用 Entry<K,V> eldest = header.after;
if (removeEldestEntry(eldest)) {
removeEntryForKey(eldest.key);
}
.....
时,它重新排列列表顺序,它将该键放在标题节点之前(比如说“b”),因此它变为
get(Object key)
只想澄清一下。
答案 0 :(得分:10)
<"a", "a">
将首先删除: - )也许;默认情况下,LinkedHashMap
使用插入订单,而不是访问顺序 ...
直接来自the specification:
Map
接口的哈希表和链表实现,具有可预测的迭代顺序。此实现与HashMap
的不同之处在于它维护了一个贯穿其所有条目的双向链表。此链接列表定义迭代排序,通常是键插入映射的顺序(插入顺序)。
话虽如此,LinkedHashMap
也支持 access-order ;
提供了一个特殊的
constructor
来创建链接的哈希映射,其迭代顺序是上次访问其条目的顺序,从最近访问到最近访问( access-order < / em>的)。这种地图非常适合构建LRU缓存。调用put
或get
方法会导致访问相应的条目(假设它在调用完成后存在)。
因此,如果您使用插入订单,则订单不会从get("b")
更改;如果您正在使用访问顺序(通常是LRU缓存 ;-),则将更改订单。
还有其他问题吗? : - )