146. LRU 快取機制
阿新 • • 發佈:2021-12-01
146. LRU 快取機制
(1)直接使用LinkedHashMap
package 連結串列; import java.util.LinkedHashMap; import java.util.Map; public class LRUCache extends LinkedHashMap<Integer, Integer> { private int capacity; public LRUCache(int capacity) { super(capacity, 0.75F, false); this.capacity = capacity; }public int get(int key) { return super.getOrDefault(key, -1); } public void put(int key, int value) { super.put(key, value); } @Override protected boolean removeEldestEntry(Map.Entry eldest) { return size() > capacity; } }
(2)利用hashMap和雙向連結串列實現LRU快取
package 連結串列; import java.util.HashMap; public class LRUCache2 { //雙向連結串列存元素順序 class DeListNode { int key; int val; DeListNode next; DeListNode pre; public DeListNode() { } public DeListNode(int key, int val) { this.key = key;this.val = val; } } private int capacity; private int size = 0; // hashMap儲存元素 private HashMap<Integer, DeListNode> map = new HashMap<>(); // 虛擬頭尾節點 private DeListNode head; private DeListNode tail; public LRUCache2(int capacity) { this.capacity = capacity; this.head = new DeListNode(); this.tail = new DeListNode(); head.next = tail; tail.pre = head; } // 查詢元素,如果不存在返回預設值,存在就把這個元素移動到連結串列頭部 public int get(int key) { if (map.containsKey(key)) { DeListNode deListNode = map.get(key); moveToHead(deListNode); return deListNode.val; } else { return -1; } } // 插入元素,如果元素存在就替換值,並把元素移動到前邊,移動到前邊就是先刪除再重新新增 // 如果元素不存在,就插入元素,並在雙向連結串列頭部也插入 // 容量超長了咋辦 public void put(int key, int value) { if (map.containsKey(key)) { DeListNode deListNode = map.get(key); deListNode.val = value; moveToHead(deListNode); } else { DeListNode newNode = new DeListNode(key, value); addHead(newNode); map.put(key, newNode); ++size; if (size > capacity) { DeListNode removeNode = removeTail(); map.remove(removeNode.key); --size; } } } private void addHead(DeListNode node) { // 這塊也會把新加入的節點和尾節點相連 node.next = head.next; node.pre = head; head.next.pre = node; head.next = node; } private void removeNode(DeListNode node) { DeListNode pre = node.pre; DeListNode next = node.next; pre.next = next; next.pre = pre; } private void moveToHead(DeListNode node) { removeNode(node); addHead(node); } private DeListNode removeTail() { DeListNode preNode = tail.pre; removeNode(preNode); return preNode; } }
。。