欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

LRU算法Java实现

程序员文章站 2024-03-18 12:38:34
...

最近在面试的时候,被面试官要求手写代码,其中LRU算法竟然也被要求写了。当时只说了思路,并没有写出来。

实现核心思想就是双端链表 + hashMap实现的
LRU算法的核心就是维护一个链表,当访问链表中某个节点的时候,就将该元素移动到链表的头部,如果新添加一个节点,直接加到链表的头部。如果链表大小超过一定阈值,那么链表末尾就是最近最少使用的节点,可以将它淘汰。

import java.util.HashMap;
import java.util.LinkedList;

public class LRUCache {

    private HashMap<Integer, Integer> cacheMap = new HashMap<>();
    private LinkedList<Integer> recentlyList = new LinkedList<>();  //按照从链表的开头到链表的末尾,存储的元素,按照最近使用的先后顺序排列
    private int capacity;


    public LRUCache(int capacity){
        this.capacity = capacity;
    }

    public int get(int key){
        if(!cacheMap.containsKey(key)){
            return -1;
        }

        //获取了key,则更新key在链表中的顺序
        recentlyList.remove((Integer)key);
        recentlyList.add(key);
        return cacheMap.get(key);
    }

    public void put(int key, int value){
        if(cacheMap.containsKey(key)){
            //如果map中已经包含了key,则在链表中先删除key
            recentlyList.remove((Integer) key);
        }else if(cacheMap.size() == capacity){
            //如果map的size已经到了容量上限,则链表删除最近使用的元素,即链表的头元素,同时删除map中头元素对应的键值对
            cacheMap.remove(recentlyList.removeFirst());
        }

        //储存了key,这里更新key在链表中的顺序
        recentlyList.add(key);
        cacheMap.put(key, value);
    }

    public static void main(String[] args) {
        LRUCache cache = new LRUCache(2);
        cache.put(1, 1);
        cache.put(2, 2);
        System.out.println(cache.get(1)); // returns 1
        cache.put(3, 3); // 驱逐 key 2
        System.out.println(cache.get(2)); // returns -1 (not found)
        cache.put(4, 4); // 驱逐 key 1
        System.out.println(cache.get(1)); // returns -1 (not found)
        System.out.println(cache.get(3)); // returns 3
        System.out.println(cache.get(4)); // returns 4
    }
}

相关标签: LRU算法