LeetCode题解(Java):146-LRU缓存机制

146. LRU缓存机制

https://leetcode-cn.com/problems/lru-cache/

1 - 基于 LinkedHashMap 实现

class LRUCache {
     
    private Cache<Integer, Integer> cache;
    private int maxCapacity;
    
    public LRUCache(int capacity) {
     
        cache = new Cache<>(capacity);
    }
    
    static class Cache<K, V> extends LinkedHashMap<K, V> {
     
        private static final long serialVersionUID = -1173181165859044409L;
        private final int maxCapacity;
        public Cache(int capacity) {
     
            super(capacity, 1f, true);
            this.maxCapacity = capacity;
        }
        @Override
        protected boolean removeEldestEntry(Map.Entry<K, V> eldest) {
     
            return this.size() > maxCapacity;
        }
    }
    
    public int get(int key) {
     
        return this.cache.get(key) == null ? -1 : this.cache.get(key);
    }
    
    public void put(int key, int value) {
     
        this.cache.put(key, value);
    }
}

2 - Map + 自定义Entry + 自定义链表实现

public class LRUCache<K, V> {
     
    private final Map<K, Entry<K, V>> container;
    private final int maxCapacity;
    private Entry<K, V> head;
    private Entry<K, V> tail;
    
    public LRUCache(int capacity) {
     
        this.maxCapacity = capacity;
        this.container = new HashMap<>(capacity);
        this.head = null;
        this.tail = null;
    }

    public int get(K key) {
     
        Entry<K, V> entry = container.get(key);
        if (entry == null) return -1;
        move2Head(entry);
        return (int)entry.value;
    }

    public void put(K key, V value) {
     
        Entry<K, V> entry = container.get(key);
        if (entry != null) {
     
            entry.value = value;// 存在,更新value
            move2Head(entry);
        } else {
     
            Entry<K, V> newEntry = new Entry<>(key, value);
            add2Head(newEntry);
            container.put(key, newEntry);
            if (container.size() > maxCapacity) {
     
                deleteTail();// 元素数量大于最大容量,清理最后使用的元素
            }
        }
    }

    private void add2Head(Entry<K, V> entry) {
     
        Entry<K, V> first = head;
        head = entry;
        if (first == null) {
     // 第一次插入或者head=tail=null
            tail = entry;
        } else {
     
            entry.next = first;
            first.prev = entry;
        }
    }

    private void move2Head(Entry<K, V> entry) {
     
        if (entry != head) {
     
            Entry<K, V> p = entry.prev;
            Entry<K, V> n = entry.next;
			// 处理当前节点的前后节点
            Entry<K, V> first = head;
            head = entry;
            head.prev = null;
            entry.next = first;
            first.prev = entry;
			// 插入到头结点
            p.next = n;
            if (n == null) {
     
                tail = p;
            } else {
     
                n.prev = p;
            }
        }
    }

    private void deleteTail() {
     
        if (tail == head) {
     
            tail = null;
            head = null;
            container.clear();
        } else {
     
            Entry<K, V> p = tail.prev;
            p.next = null;
            tail.prev = null;
            container.remove(tail.key);
            tail = p;
        }
    }

    private static class Entry<K, V> {
     
        K key;
        V value;
        Entry<K, V> prev;
        Entry<K, V> next;
        public Entry(K key, V value) {
     
            this.key = key;
            this.value = value;
            this.prev = null;
            this.next = null;
        }
    }
}

你可能感兴趣的:(LeetCode,Java,java,leetcode,缓存,lru)