1. 程式人生 > 其它 >146. LRU 快取機制

146. LRU 快取機制

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

。。