LRU缓存删除最不经常使用的记录

    /**
     * 设计LRU缓存结构,该结构在构造时确定大小,假设大小为K,并有如下两个功能
     * set(key,value)
     * get(key)
     * 某个key的set或get一旦发生,认为这个key的记录是最常用的
     * 当缓存的大小超过K,移除最不经常使用的记录,即set或get最久远的
     *
     */

public static void main(String[] args) {
        // TODO Auto-generated method stub
        Cache<String,String> cache = new Cache<>(5);
        cache.set("1", "1");
        cache.set("2", "2");
        cache.set("3", "3");
        cache.set("4", "4");
        cache.set("5", "5");
        System.out.println(cache.get("3"));;
        cache.set("3", "03");
        cache.set("5", "05");
        cache.set("6", "06");
        cache.set("7", "07");
        Node<String> node = cache.linkCache.head;
        while(node !=null) {
            System.out.println("node--"+node.value);
            node = node.next;
        }
        
    }

}

class Cache<k,v>{
    Map<k,Node<v>> map;
    Map<Node<v>,k> nodeMp;
    LinkCache<v> linkCache;
    int size;
    public Cache(int size) {
        this.map = new HashMap<>();
        this.nodeMp = new HashMap<>();
        this.size = size;
        this.linkCache = new LinkCache<>();
    }
    public void set(k key,v value) {
        Node<v> node = new Node<>(value);
        //先判断当前是否存该value
        Node<v> n = map.get(key);
        if(n !=null) {
            n.value = value;
            get(key);//将改节点置顶
        }else {
            map.put(key, node);
            nodeMp.put(node, key);
            linkCache.addHead(node);
            if(map.size()>this.size) {
                Node<v> tail = linkCache.removeTail();
                k k = nodeMp.get(tail);
                nodeMp.remove(tail);
                map.remove(k);
            }
        }
    }
    public v get(k key) {
        Node<v> node =  map.get(key);
        Node<v> pre = node.pre;
        Node<v> next = node.next;
        node.next = null;
        node.pre = null;
        if(pre !=null && next !=null) {
            pre.next = next;
            next.pre = pre;
            linkCache.addHead(node);//放入头部
        }else if(next == null) { //当前节点是尾节点
            linkCache.tail = pre;
            pre.next = null;
            linkCache.addHead(node);//放入头部
        }
        //pre == null 当前节点是head 不用处理
            
        return node.value;
    }
    
    
}

class LinkCache<T>{
    Node<T> head;
    Node<T> tail;
    public void addHead(Node<T> node) {
        if(head == null) {
            this.head = node;
            this.tail = node;
        }else {
            node.next = this.head;
            this.head.pre = node;
            this.head = node;
        }
    }
    public Node<T> removeTail() {
        if(this.tail !=null) {
            Node<T> node = tail.pre;
            if(node !=null) {
                node.next = null;
                this.tail = node;
            }else {
                this.head = null;
                this.tail = null;
            }
            return this.tail;
        }
        return null;
    }
    
}

/*
 * 作为自定义链表公共类
 */
public  class Node<T> {
     public T value;
     public Node<T> pre;
     public Node<T> next;
     public Node(T value){
         this.value = value;
     }
}
 

上一篇:redis的淘汰机制的分享


下一篇:常见算法-LinkedHashMap实现LRU