import java.util.HashMap;
public class LRUCache {
//循环双向链表
class DLinkedNode{
int key;
int value;
DLinkedNode prev;
DLinkedNode next;
public DLinkedNode(){
}
public DLinkedNode(int key,int value){
this.key = key;
this.value = value;
}
}
private HashMap<Integer,DLinkedNode> map = new HashMap<>();
private int size; //当前的大小
private int cap; //表示容量
private DLinkedNode head,tail; //使用一个虚拟头和虚拟尾节点 判断的时候容易处理
public LRUCache(int cap){
this.size = 0;
this.cap = cap;
head = new DLinkedNode();
tail = new DLinkedNode();
head.next = tail;
tail.next = head;
}
public int get(int key){
DLinkedNode node = map.get(key);
if(node == null){
return -1;
}
//如果存在 将当前节点移动到头部
moveCurToHead(node);
return node.value;
}
public void put(int key,int value){
DLinkedNode node = map.get(key);
if(node == null){
//表示set的key不存在 则新建节点插入头部
DLinkedNode newNode = new DLinkedNode(key, value);
map.put(key,newNode);
size++;
addNodeToHead(newNode);
//这时需要判断当前的长度是否大于最大容量 如果大于就需要把最后一个节点移除
if(size > cap){
DLinkedNode tail = removeTail();
map.remove(tail.key);
size--;
}
}else{
//否则 修改值 并移动到头部
node.value = value;
moveCurToHead(node);
}
}
public DLinkedNode removeTail() {
//这里有一个虚拟尾部节点
DLinkedNode node = tail.prev;
removeNode(node);
return node;
}
public void moveCurToHead(DLinkedNode node) {
removeNode(node);
addNodeToHead(node);
}
public void addNodeToHead(DLinkedNode newNode){
newNode.next = head.next;
newNode.prev = head;
head.next.prev = newNode;
head.next = newNode;
}
public void removeNode(DLinkedNode node){
node.prev.next = node.next;
node.next.prev = node.prev;
}
public static void main(String[] args) {
LRUCache lru = new LRUCache(4);
// 1 2 3 4 1 5 应该是2没有
lru.put(1, 1);
lru.put(2, 2);
lru.put(3, 3);
lru.put(4, 4);
System.out.println(lru.get(1));
lru.put(5, 5);
System.out.println(lru.get(3));
}
}
快手一面 手写LRU
猜你喜欢
转载自blog.csdn.net/xiaoning9299/article/details/132435227
今日推荐
周排行