LRU(Least Recently Used)
LRU 算法的设计原则是:如果一个数据在最近一段时间没有被访问到,那么在将来它被访问的可能性也很小。也就是说,当限定的空间已存满数据时,应当把最久没有被访问到的数据淘汰。
提供一种基于map+链表的LRU缓存实现
public class LRUBaseHashMap {
private HashMap<String, LRUNode> map;
private int capacity;
private LRUNode tail;
private LRUNode head;
public void set(String key, Object value) {
LRUNode node = map.get(key);
if (node != null) {
// 原缓存已经存在了
node.value = value;
remove(node, false);
} else {
// 原缓存不存在
node = new LRUNode(key, value);
if (map.size() >= capacity) {
//超出容量,淘汰过期缓存
remove(tail, true);
}
map.put(key, node);
}
setHead(node);
}
public Object get(String key) {
LRUNode node = map.get(key);
if (node != null) {
//最新读取的缓存放到链表头
remove(node, false);
setHead(node);
return node.value;
}
return null;
}
public void del(String key) {
LRUNode node = map.get(key);
if (node != null) {
remove(node, true);
}
}
private void remove(LRUNode node, boolean remove) {
if (node.prev != null) {
node.prev.next = node.next;
} else {
head = node.next;
}
if (node.next != null) {
node.next.prev = node.prev;
} else {
tail = node.prev;
}
node.next = null;
node.prev = null;
if (remove) {
map.remove(node.key);
}
}
private void setHead(LRUNode node) {
if (head != null) {
node.next = head;
head.prev = node;
}
head = node;
if (tail == null) {
tail = node;
}
}
public LRUBaseHashMap(int capacity) {
this.capacity = capacity;
this.map = new HashMap<>();
}
public static class LRUNode {
public String key;
public Object value;
LRUNode prev;
LRUNode next;
public LRUNode(String key, Object value) {
this.key = key;
this.value = value;
}
}
}