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

}

。。

上一篇:14.LRU缓存机制


下一篇:LRU缓存