LeetCode146 LRU Cache

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

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);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值