Java实现LRU缓存方案

  • LRU 是 Least Recently Used 的缩写,意思是 最近最少使用 。LRU 缓存就是使用这种原理实现,就是缓存一定的数据,超过设定的最大值以后就移除过期的数据。

  • 解决方案:可以使用两个数据结构实现一个LRU缓存。
    1)使用双向链表实现的队列,队列的最大容量为缓存的大小。在使用的过程中把最近使用的页面移动到队列头,最近没有使用的放在后面。
    2)使用一个哈希表,把页号最为键,把缓存在队列中的节点地址作为值。

具体代码如下:


public class LRU {
	// 存储值
    private ArrayDeque<Integer> queue = new ArrayDeque<>();
    private HashSet<Integer> hashSet = new HashSet<>();
    // 缓存大小
    private int cacheSize;

    public LRU(int cacheSize) {
        this.cacheSize = cacheSize;
    }

    // 判断队列是否已满
    private boolean isQueueFull() {
        return queue.size() == cacheSize;
    }

    private void enqueue(int pageNum) {
        if (isQueueFull()) {
            hashSet.remove(queue.getLast());
            // 移除最后一个 如果使用  queue.removeLast(); 如果是 null 会抛出异常 使用 queue.pollLast();如果是 null 则返回 null
            queue.pollLast();
        }
        queue.addFirst(pageNum);
        hashSet.add(pageNum);
    }

    public void accessPage(int pageNum) {
        if (!hashSet.contains(pageNum)) {
            // 如果没有缓存则添加进去
            enqueue(pageNum);
        } else if (pageNum != queue.getFirst()) {
            // 如果在缓存中则移动到队首
            queue.remove(pageNum);
            queue.addFirst(pageNum);
        }
    }

    public void printQueue() {
        while (!queue.isEmpty()) {
            System.out.println(queue.pop() + " ");
        }
    }
}

  • 使用方式
	@Test
    public void test2() {
        LRU lru = new LRU(3);
        lru.accessPage(1);
        lru.accessPage(2);
        lru.accessPage(3);
        lru.accessPage(4);
        lru.accessPage(5);
        lru.accessPage(6);
        lru.accessPage(6);
        lru.accessPage(5);
        lru.printQueue();
    }

运行结果为:5 6 4

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章