复习LRU算法,落实到代码加深一下印象
import java.util.HashMap; /** * 手写LRU算法 * @param <K> * @param <V> */ public class LRU<K,V> { private class Node { // 前结点 private Node prev; // 后结点 private Node next; // 键 private K key; // 值 private V value; } // 队列头尾 private Node head, tail; // 队列长度 private int capacity; // 存储结点 private HashMap<K, Node> map = new HashMap<>(); // 构造函数初始化 public LRU(int capacity) { this.capacity = capacity; this.map = new HashMap<>(capacity); } // 存储键值 public void put(K k, V v){ Node node = map.get(k); if (node != null) { node.value = v; // 移动到队首 moveToHead(node); }else { node = new Node(); node.key = k; node.value = v; // 超过阈值,移除队尾 if (map.size() == capacity) { removeTail(); } // 新增放到队首 addToHead(node); map.put(k,node); } } // 根据key获取值 public V get(K k) { Node node = map.get(k); if (node == null) { return null; } // 移动到队首 moveToHead(node); return node.value; } // 将结点移动到队首 public void moveToHead(Node node) { if (node == head) { return; }else if (node == tail) { tail.prev.next = null; tail = tail.prev; }else { node.prev.next = node.next; node.next.prev = node.prev; } node.prev = head.prev; node.next = head; head.prev = node; head = node; } // 添加结点到队首 public void addToHead(Node node) { if (map.isEmpty()) { head = node; tail = node; }else { node.next = head; head.prev = node; head = node; } } // 移除队尾 public void removeTail() { map.remove(tail.key); Node prev = tail.prev; if (prev != null) { prev.next = null; tail = prev; } } @Override public String toString() { return map.keySet().toString(); } public static void main(String[] args) { LRU<String, String> lru = new LRU<>(3); lru.put("a","a"); lru.put("b","b"); lru.put("c","c"); lru.put("d","d"); System.out.println(lru.toString()); // 输出[d,c,b] } }