146. LRU缓存机制java
class LRUCache { class Node { int key; int val; Node pre; Node next; public Node() {} public Node(int key, int val) { this.key = key; this.val = val; } } // 哈希表中的node和双链表的node是同一个结点 private HashMap<Integer, Node> cache; private Node dummyHead; private Node dummyTail; private int size; private int capacity; public LRUCache(int capacity) { cache = new HashMap<>(); dummyHead = new Node(); dummyTail = new Node(); dummyHead.next = dummyTail; dummyTail.pre = dummyHead; this.capacity = capacity; this.size = 0; } public int get(int key) { // 先获取看看结点存不存在 Node node = cache.get(key); // 若是存在的话,将当前访问的结点移动到链表头,而且返回值 if (node != null) { moveToHead(node); return node.val; } // 不存在的话就返回-1 return -1; } public void put(int key, int value) { // 也是先看看结点是否存在 Node node = cache.get(key); // 若是存在,那么要作的操做就是将结点移动到链表头,而后更新结点值便可 if (node != null) { node.val = value; moveToHead(node); } else { // 若是不存在的话咱们就要建立新结点插入 Node newNode = new Node(key, value); // 先添加到哈希表中 cache.put(key, newNode); // 再添加到链表中 addToHead(newNode); // 而且长度+1 size++; // 由于咱们设定最大容量,咱们还要判断新put的结点后,容量是否超过了capacity,超过了话,删除最后一个结点,而且长度-1 if (size > capacity) { Node tail = removeTail(); cache.remove(tail.key); size--; } } } /** * 将node移动到最前面 */ private void moveToHead(Node node) { if (size > 0 && size <= capacity) { remove(node); addToHead(node); } } /** * 删除node结点 */ private void remove(Node node) { if (size > 0) { node.pre.next = node.next; node.next.pre = node.pre; } } /** * 删除最后一个结点 */ private Node removeTail() { if (size > 0) { Node node = dummyTail.pre; remove(node); return node; } return null; } /** * 添加新结点到第一位去 */ private void addToHead(Node node) { node.next = dummyHead.next; dummyHead.next = node; node.next.pre = node; node.pre = dummyHead; } }