小念子

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

运用你所掌握的数据结构,设计和实现一个  LRU (最近最少使用) 缓存机制 。
实现 LRUCache 类:

LRUCache(int capacity) 以正整数作为容量 capacity 初始化 LRU 缓存
int get(int key) 如果关键字 key 存在于缓存中,则返回关键字的值,否则返回 -1 。
void put(int key, int value) 如果关键字已经存在,则变更其数据值;如果关键字不存在,则插入该组「关键字-值」。当缓存容量达到上限时,它应该在写入新数据之前删除最久未使用的数据值,从而为新的数据值留出空间。
 

 

 解答:

方法1:使用额外的list作为辅助

public class LRUCache {
    private int capacity;
    private Map<Integer, Integer> map;
    private List<Integer> list;
    
    public LRUCache(int capacity) {
        this.capacity = capacity;
        map = new HashMap<Integer, Integer>();
        list = new LinkedList<Integer>();
    }
    
    public int get(int key) {
        if (map.containsKey(key)) {
            int pos = list.indexOf(key);
            list.remove(pos);
            list.add(key);
            return map.get(key);
        }
        return -1;
    }
    
    public void put(int key, int value) {
        if (map.containsKey(key)) {
            int pos = list.indexOf(key);
            list.remove(pos);
            list.add(key);
            map.put(key, value);
        } else {
            if (map.size() == capacity) {
                int removeKey = list.get(0);
                list.remove(0);
                map.remove(removeKey);
            }
            map.put(key, value);
            list.add(key);
        }
    }
}

方法2:利用LinkedHashMap的插入序(默认)

public class LRUCache1 {
    private int capacity;
    private LinkedHashMap<Integer, Integer> map;
    
    public LRUCache1(int capacity) {
        this.capacity = capacity;
        map = new LinkedHashMap<>();
    }
    
    public int get(int key) {
        if (map.containsKey(key)) {
            int value = map.get(key);
            map.remove(key);
            map.put(key, value); // 先删后加,保证最新
            return value;
        }
        return -1;
    }
    
    public void put(int key, int value) {
        if (map.containsKey(key)) {
            map.remove(key);
            map.put(key, value);
        } else {
            if (map.size() == capacity) {
                // 删除第一个元素, 即head的下一个(head是空)
                Iterator<Map.Entry<Integer, Integer>> iterator = map.entrySet().iterator();
                iterator.next();
                iterator.remove();
            }
            map.put(key, value);
        }
    }
}

方法3:利用LinkedHashMap的访问序(非默认,构造函数中进行设置)

public class LRUCache2 {
    private LinkedHashMap<Integer, Integer> map;
    
    public LRUCache2(int capacity) {
        // accessOrder:false--基于插入顺序(默认) true--基于访问顺序
        map = new LinkedHashMap<Integer, Integer>(0, 0.75f, true) {
            private static final long serialVersionUID = 1L;

            @Override
            protected boolean removeEldestEntry(Map.Entry<Integer, Integer> arg0) {
                // TODO Auto-generated method stub
                return size() > capacity; // 当put进新的值方法返回true时,便移除该map中最老的键和值
            }
            
        };
    }
    
    public int get(int key) {
        return map.getOrDefault(key, -1);
    }
    
    public void put(int key, int value) {
        map.put(key, value);
    }
}

 

posted on 2021-01-14 11:30  小念子  阅读(73)  评论(0编辑  收藏  举报