Design and implement a data structure for Least Recently Used (LRU) cache. It should support the following operations: get
and set
.
get(key)
- Get the value (will always be positive) of the key if the key exists in the cache, otherwise return -1.
set(key, value)
- Set or insert the value if the key is not already present. When the cache reached its capacity, it should invalidate the least recently used item before inserting a new item.
LRU是Least Recently Used 近期最少使用算法。
LRU(least recently used)最少使用。
假设 序列为 4 3 4 2 3 1 4 2
物理块有3个 则
首轮 4调入内存 4
次轮 3调入内存 3 4
之后 4调入内存 4 3
之后 2调入内存 2 4 3
之后 3调入内存 3 2 4
之后 1调入内存 1 3 2(因为最少使用的是4,所以丢弃4)
之后 4调入内存 4 1 3(原理同上)
最后 2调入内存 2 4 1
public class LRUCache {
public class DListNode {
public int key;
public int val;
public DListNode prev;
public DListNode next;
public DListNode( int key, int val ){
this.key = key;
this.val = val;
prev = null;
next = null;
}
}
private int maxSize;
private Map<Integer,DListNode> map;
private DListNode head, tail;
public LRUCache(int capacity) {
this.maxSize = capacity;
map = new HashMap<Integer,DListNode>();
head = new DListNode(-1,-1);
tail = new DListNode(-1,-1);
tail.next = head;
head.prev = tail;
}
//当key存在时,将其移至尾节点
public int get(int key) {
if( map.containsKey(key) ){
DListNode current = map.get(key);
remove( current );
add2Tail( current );
return current.val;
}else{
return -1;
}
}
private void remove( DListNode p ){
p.prev.next = p.next;
p.next.prev = p.prev;
}
private void add2Tail( DListNode p ){
p.next = tail.next;
p.next.prev = p;
p.prev = tail;
tail.next = p;
}
public void set(int key, int value) {
if( get(key)==-1 ){
//当cache中的元素个数达到最大值时,移除head节点的前驱(最后一个元素)
if( map.size()==this.maxSize){
map.remove(head.prev.key);
remove(head.prev);
}
//新建节点,添加至tail
DListNode node = new DListNode( key, value );
add2Tail(node);
map.put(key, node);
}else{
map.get(key).val = value;
}
}
}