Design and implement a data structure for Least Recently Used (LRU) cache. It should support the following operations: get and set.
get(key) - Get the value (will always be positive) of the key if the key exists in the cache, otherwise return -1.
set(key, value) - Set or insert the value if the key is not already present. When the cache reached its capacity, it should invalidate the least recently used item before inserting a new item.
该题就是设计一个LRU(最近最少访问的cache)Cache,支持get和set方法。当缓冲区满的时候,根据最近最少访问的原则将新的item插入即可。 思路:键值对的插入很容易想到Map,LinkedListMap就有两种插入方式 accessOrder布尔值为true时为 access-order(访问顺序)进行插入,也就是按照最近最少访问的原则插入,false时为insertion-order(插入顺序),即按插入的先后顺序进行插入。
A special {@link #LinkedHashMap(int,float,boolean) constructor} is provided to create a linked hash map whose order of iteration is the order in which its entries were last accessed, from least-recently accessed to most-recently (access-order). This kind of map is well-suited to building LRU caches.
通过阅读源代码,我们发现LinkedHashMap(int,float,boolean) 构造方法是解决该题的关键。
public LinkedHashMap(int initialCapacity, float loadFactor,boolean accessOrder)
{
super(initialCapacity, loadFactor);
this.accessOrder = accessOrder;
}
构造函数中的三个参数分别是,initialCapacity初始容量,loadFactor荷载因子,accessOreder是否为访问顺序。
当我们选择accessOrder方式时,当Cache达到最大容量时要删除最近最少访问的元素,所以要重载该方法。
The {@link #removeEldestEntry(Map.Entry)} method may be overridden to impose a policy for removing stale mappings automatically when new mappings are added to the map.
removeEldestEntry当新的映射添加到map中,我们可能需要重载该方法来自动删除旧的映射。这里的映射就是键值对的意思。
怎样重载,在注释中也给出了例子。让我们来看看注释。
Returns true if this map should remove its eldest entry.This method is invoked by put and putAll after inserting a new entry into the map. It provides the implementor with the opportunity to remove the eldest entry each time a new one is added. This is useful if the map represents a cache: it allows the map to reduce memory consumption by deleting stale entries.
如果map需要删除旧的entry,return返回true。当用put和putAll方法初入新的entrys时该方法就会被调用。如果该map代表cache时。通过删除旧的entry来达到节省内存消耗的作用。
Sample use: this override will allow the map to grow up to 100 entries and then delete the eldest entry each time a new entry is added, maintaining a steady state of 100 entries.
例如,当map增加到100entries后,需要删除旧的entry来添加新的entry,维持100固定的长度。
private static final int MAX_ENTRIES = 100;
protected boolean removeEldestEntry(Map.Entry eldest)
{
return size() > MAX_ENTRIES;
}
好了,结合少量的源码分析和题目的理解,我们来实现LRUCache的功能如下。
import java.util.LinkedHashMap;
import java.util.Map;
public class LRUCache<K, V> extends LinkedHashMap<Integer, Integer>
{
private static final long serialVersionUID = 1L;
private int capacity;
public LRUCache(int capacity)
{
super(capacity, 0.75f, true);
this.capacity = capacity;
}
@Override
protected boolean removeEldestEntry(Map.Entry<Integer, Integer> eldest)
{
// TODO Auto-generated method stub
return size() > capacity;
}
public int get(int key)
{
// TODO Auto-generated method stub
if(super.get(key)==null)return -1;
return super.get(key);
}
public void set(int key, int value)
{
// TODO Auto-generated method stub
super.put(key,value);
}
}

本文介绍了一种使用Java实现LRU缓存的方法。利用LinkedHashMap提供的特定构造方法及迭代顺序特性,使得缓存在容量达到上限时能够自动移除最近最少使用的项,保持缓存的有效性。

1536

被折叠的 条评论
为什么被折叠?



