在以下LRU实现的get方法中有什么用map.remove()?

时间:2018-05-16 12:32:47

标签: java lru


我正在研究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);
    }
}

2 个答案:

答案 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并将其归还。这种方式确实成为最新的方式。