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;
}
}
}