我正在研究LRU并使用下面的代码片段来理解它的实现。请告诉我map.remove(key)
中get(int key)
方法调用的用法。我们不能只使用map.put(key,value)
,它会在地图中更新密钥的输入。
我在下面的代码中提出来。
class LRUMap<K, V> extends LinkedHashMap<K, V>{
private final int MAX_NUM;
public LRUMap(int capacity) {
super(capacity);
MAX_NUM = capacity;
}
protected boolean removeEldestEntry(Map.Entry eldest) {
return /*true*/ size() > MAX_NUM;
}
}
public class LRU {
LRUMap<Integer, Integer> map;
public LRU(int capacity) {
map = new LRUMap<Integer, Integer>(capacity);
}
public int get(int key) {
if (map == null || map.get(key) == null)
return -1;
int value = map.get(key);
map.remove(key);
map.put(key, value);
return value;
}
public void set(int key, int value) {
if (map == null) return;
get(key);
map.put(key, value);
}
}
答案 0 :(得分:8)
此LRUMap
扩展LinkedHashMap
,它按照插入密钥的顺序维护Map
条目的链接列表(第一个键是添加到{的第一个键{1}})。
当您实现最近最少使用的数据结构时,您想知道哪个元素最近最少使用。当你的空间不足时,这是你首先要删除的元素。
现在,如果我们查看Map
Javadoc:
这个实现与HashMap的不同之处在于它维护着一个运行所有条目的双向链表。此链接列表定义迭代排序,通常是键插入映射的顺序(插入顺序)。 请注意,如果将密钥重新插入地图,则不会影响广告订单。 (如果m.containsKey(k)在调用之前立即返回true,则调用m.put(k,v)时,将密钥k重新插入到映射m中。)
我们看到,为LinkedHashMap
中已存在的密钥调用put(k,v)
不会影响广告订单。
因此,当您访问Map
的密钥时,必须先将其从Map
中删除,然后重新添加,然后将其移至链接列表的末尾,并且有效地将其标记为最近使用的密钥(这是最后插入的密钥)。
请注意,LinkedHashMap
方法也会调用set()
,这意味着如果密钥已经在get()
中,它也会将密钥移动到链接列表的末尾。
答案 1 :(得分:4)
LRU =最近最近使用的缓存。
当您使用Key
时,它应该成为最近使用的。简单地更新它不会使它最近使用,因为它不会更改基础LinkedList
中的索引。
因此remove
并将其归还。这种方式确实成为最新的方式。