手撕算法-LRU缓存
import java.util.Map;
import java.util.HashMap;
public class LRUCache<K, V> {
private Map<K, Node<K, V>> cacheMap = null;
private final int capacity;
private final Node<K, V> head;
private final Node<K, V> tail;
public LRUCache(int capacity) {
this.capacity = capacity;
cacheMap = new HashMap<>();
head = new Node<>();
tail = new Node<>();
head.next = tail;
tail.prev = head;
}
public V get(K key) {
// 从Map中取值
Node<K, V> node = cacheMap.get(key);
if (node == null) {
// 如果没有,则返回null
return null;
}
// 如果缓存中有,移动到链表头部,最近有使用
moveToHead(node);
return node.value;
}
public void put(K key, V value) {
// 如果缓存中有,则更新值,并移动到链表头部
Node<K, V> node = cacheMap.get(key);
if (node != null) {
node.value = value;
moveToHead(node);
return;
}
// 缓存中没有,则创建一个节点,并添加到链表头部
node = new Node<>();
node.value = value;
cacheMap.put(key, node);
moveToHead(node);
// 缓存已满,则删除链表尾部节点,尾部为最少使用的节点
if (cacheMap.size() > capacity) {
removeTail();
}
}
public void moveToHead(Node<K, V> node) {
// 将节点从原位置删除
remove(node);
// 添加到链表头部
Node<K, V> temp = head.next;
head.next = node;
node.prev = head;
node.next = temp;
temp.prev = node;
}
public void remove(Node<K, V> node) {
if (node.prev == null || node.next == null) {
// 链表头,或链表尾,直接返回
return;
}
Node<K, V> temp = node.prev;
temp.next = node.next;
node.next.prev = temp;
}
public void removeTail() {
// 移除尾节点
Node<K, V> temp = tail.prev;
remove(temp);
}
public static void main(String... args) {
LRUCache<Integer, Integer> lruCache = new LRUCache<>(3);
lruCache.put(1, 1);
lruCache.put(2, 2);
lruCache.put(3, 3);
lruCache.printCache();
lruCache.get(2);
lruCache.printCache();
lruCache.put(4, 4);
lruCache.printCache();
}
public void printCache() {
Node<K, V> temp = head;
while (temp != null) {
if (temp == head || temp == tail) {
temp = temp.next;
continue;
}
System.out.print(temp.value + "\t");
temp = temp.next;
}
System.out.println("\n-------------------");
}
public static class Node<K, V> {
K key;
V value;
Node<K, V> prev;
Node<K, V> next;
}
}
积跬步以致千里,积小流以成江海。
2016年5月之前的博文发布于51cto,链接地址:shamrock.blog.51cto.com
2016年5月之后博文发布与cnblogs上。
Github地址 https://github.com/umgsai
Keep moving~!!!
2016年5月之前的博文发布于51cto,链接地址:shamrock.blog.51cto.com
2016年5月之后博文发布与cnblogs上。
Github地址 https://github.com/umgsai
Keep moving~!!!

浙公网安备 33010602011771号