LRU(Least Recently Used)即最近最少使用,是一种内存管理算法。
import java.util.HashMap;
import java.util.Map;
/**
* 使用哈希表和双向链表实现LRU
*/
class LRU {
class Node {
int key;
int value;
Node prev;
Node next;
public Node(int key, int value) {
this.key = key;
this.value = value;
}
}
private int capacity;//缓存容量
private Map<Integer, Node> map;//存储缓存键值对的哈希表
private Node head;//链表头部
private Node tail;//链表尾部
public LRU(int capacity) {
this.capacity = capacity;
this.map = new HashMap<>();
this.head = new Node(0, 0);//创建头部节点
this.tail = new Node(0, 0);//创建尾部节点
this.tail.prev = this.head;//尾部节点指向头部节点
this.head.next = this.tail;//头部节点指向尾部节点
}
public int get(int key) {
if (!map.containsKey(key)) {
return -1;
}
Node node = map.get(key);
removeNode(node);//将节点移除当前位置
addToHead(node);//将节点移动到链表头部
return node.value;
}
public void put(int key, int value) {
if (map.containsKey(key)) {
Node node = map.get(key);
node.value = value;//更新节点值
removeNode(node);//将节点移除当前位置
addToHead(node);//将节点移动到链表头部
} else {
if (map.size() >= capacity) {
Node tailPrev = tail.prev;//获取尾部的前驱
removeNode(tailPrev);
map.remove(tailPrev.key);//从哈希表中移除对应的键值对
}
Node newNode = new Node(key, value);
map.put(key, newNode);
addToHead(newNode);
}
}
public void removeNode(Node node) {
node.prev.next = node.next;
node.next.prev = node.prev;
}
public void addToHead(Node node) {
//注意顺序
node.next = head.next;
head.next.prev = node;
node.prev = this.head;
this.head.next = node;
}
}
public class LRUCache {
public static void main(String[] args) {
LRU cache = new LRU(2);
cache.put(1, 1);
cache.put(2, 2);
System.out.println(cache.get(2));//2
cache.put(3, 3);
System.out.println(cache.get(1));//-1
cache.put(4, 4);
System.out.println(cache.get(2));//-1
System.out.println(cache.get(3));//3
System.out.println(cache.get(4));//4
}
}
运行结果