LRU缓存思想

package com.banban.CeShi;


import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Stack;

/**
 *  实现一个长度为n的LRU缓存,即超出长度后,丢弃最少被使用的元素
 *      方法一:
 *          使用map+Stack实现,按顺序访问
 *      方法二:
 *          LinkedHashMap实现,按顺序访问
 *      方法三:
 *          双向链表+hashmap实现,按顺序访问(已实现)
 */
 实现一:慢慢理解
public class LRUCache<K,V> {
    private Stack<K> stack;
    private HashMap<K,V>  hashMap;
    private int size;

    public LRUCache(int size) {
        this.stack = new Stack<>();
        this.hashMap = new HashMap<K, V>(size);
        this.size = size;
    }

    public V get(K k){
        if (!stack.contains(k)){
            return null;
        }else {
            stack.remove(k);
            stack.push(k);
            return hashMap.get(k);
        }
    }
    public void put(K k,V v){
        if (stack.contains(k)){
            stack.remove(k);
            hashMap.remove(k);
        }else {
            if (stack.size() == size){
                K remove = stack.remove(0);
                hashMap.remove(remove);
            }
        }
        stack.push(k);
        hashMap.put(k, v);
    }
}
实现二:如此方便
class LRUCache2<K,V> extends LinkedHashMap<K,V>{
    private int max_cache;

    public LRUCache2(int max_cache) {
        super(max_cache, 0.75f, true);
        this.max_cache = max_cache;
    }

    @Override
    protected boolean removeEldestEntry(Map.Entry eldest) {
        return super.size()>max_cache;
    }
}

实现三:建议自己看代码走流程一遍。
public class LRUCache {
    /**
     * 链表节点
     * @author Administrator
     *
     */
    class CacheNode {
        ……
    }
    private int cacheSize;//缓存大小
    private Hashtable nodes;//缓存容器
    private int currentSize;//当前缓存对象数量
    private CacheNode first;//(实现双链表)链表头
    private CacheNode last;//(实现双链表)链表尾


}

public class LRUCache {
    /**
     * 链表节点
     * @author Administrator
     *
     */
    class CacheNode {
        CacheNode prev;//前一节点
        CacheNode next;//后一节点
        Object value;//值
        Object key;//键
        CacheNode() {
        }
    }

      private int cacheSize;//缓存大小
      private Hashtable nodes;//缓存容器
      private int currentSize;//当前缓存对象数量
      private CacheNode first;//(实现双链表)链表头
      private CacheNode last;//(实现双链表)链表尾

    public LRUCache(int i) {
        currentSize = 0;
        cacheSize = i;
        nodes = new Hashtable(i);//缓存容器
    }

    /**
     * 获取缓存中对象
     * @param key
     * @return
     */
    public Object get(Object key) {
        CacheNode node = (CacheNode) nodes.get(key);
        if (node != null) {
            moveToHead(node);
            return node.value;
        } else {
            return null;
        }
    }

    /**
     * 添加缓存
     * @param key
     * @param value
     */
    public void put(Object key, Object value) {
        CacheNode node = (CacheNode) nodes.get(key);

        if (node == null) {
            //缓存容器是否已经超过大小.
            if (currentSize >= cacheSize) {
                if (last != null)//将最少使用的删除
                    nodes.remove(last.key);
                removeLast();
            } else {
                currentSize++;
            }

            node = new CacheNode();
        }
        node.value = value;
        node.key = key;
        //将最新使用的节点放到链表头,表示最新使用的.
        moveToHead(node);
        nodes.put(key, node);
    }
    /**
     * 将缓存删除
     * @param key
     * @return
     */
    public Object remove(Object key) {
        CacheNode node = (CacheNode) nodes.get(key);
        if (node != null) {
            if (node.prev != null) {
                node.prev.next = node.next;
            }
            if (node.next != null) {
                node.next.prev = node.prev;
            }
            if (last == node)
                last = node.prev;
            if (first == node)
                first = node.next;
        }
        return node;
    }
    public void clear() {
        first = null;
        last = null;
    }
    /**
     * 删除链表尾部节点
     *  表示 删除最少使用的缓存对象
     */
    private void removeLast() {
        //链表尾不为空,则将链表尾指向null. 删除连表尾(删除最少使用的缓存对象)
        if (last != null) {
            if (last.prev != null)
                last.prev.next = null;
            else
                first = null;
            last = last.prev;
        }
    }

    /**
     * 移动到链表头,表示这个节点是最新使用过的
     * @param node
     */
    private void moveToHead(CacheNode node) {
        if (node == first)
            return;
        if (node.prev != null)
            node.prev.next = node.next;
        if (node.next != null)
            node.next.prev = node.prev;
        if (last == node)
            last = node.prev;
        if (first != null) {
            node.next = first;
            first.prev = node;
        }
        first = node;
        node.prev = null;
        if (last == null)
            last = first;
    }

}
©️2020 CSDN 皮肤主题: 技术黑板 设计师:CSDN官方博客 返回首页