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

    。。

  • 相关阅读:
    select 1 from ... sql语句中的1代表什么意思?
    装饰者模式
    Dao层抽取BaseDao公共方法
    DBUtils工具类
    java Page分页显示
    QTP
    Gym 100513F Ilya Muromets(前缀和)
    AcWing1165 单词环(01分数规划)
    AcWing904 虫洞(spfa判负环)
    AcWing1148 秘密的奶牛运输(次小生成树)
  • 原文地址:https://www.cnblogs.com/guoyu1/p/15630465.html
Copyright © 2020-2023  润新知