zoukankan      html  css  js  c++  java
  • 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;
        }
    
    }

    。。

  • 相关阅读:
    android stagefright awesomeplayer 分析
    stagefright框架(七)-Audio和Video的同步
    stagefright框架(六)-Audio Playback的流程
    Windows Sockets Error Codes
    编译boost (windows msvc14)
    golang windows程序获取管理员权限(UAC ) via gocn
    阿里云容器服务--配置自定义路由服务应对DDOS攻击
    store / cache 系列
    一些项目感悟
    protobuf-3.0.0-beta-2 windows编译 x64/x86
  • 原文地址:https://www.cnblogs.com/guoyu1/p/15630465.html
Copyright © 2011-2022 走看看