带过期时间的LRUCache java实现

实现代码,惰性删除过期节点

import java.util.*;

public class LRUWithExpire {
    static class ListNode{
        int key;
        int value;
        //单位为毫秒
        long expire;

        ListNode pre;

        ListNode next;

        public ListNode(int key, int value, long expire){
            this.key = key;
            this.value = value;
            this.expire = System.currentTimeMillis() + expire;
        }
        public ListNode(){}
    }

    static Map<Integer,ListNode> nodeMap;

    static Map<Long, Set<ListNode>> expireMap;

    static PriorityQueue<Long> queue;

    static int size;

    static int capacity;

    static ListNode head;
    static ListNode tail;

    public LRUWithExpire(int capacity){
        nodeMap = new HashMap<>();
        expireMap = new HashMap<>();
        this.size = 0;
        this.capacity = capacity;
        queue = new PriorityQueue<>();
        head = new ListNode();
        tail = new ListNode();
        head.next = tail;
        tail.pre = head;
    }

    public int get(int key){
        if(!nodeMap.containsKey(key)){
            return -1;
        }
        ListNode node = nodeMap.get(key);
        long now = System.currentTimeMillis();
        if(node.expire<=now){
            return -1;
        }
        moveToHead(node);
        return node.value;
    }


    public void put(int key, int value, long expire){
        removeByExpire();
        if(nodeMap.containsKey(key)){
            ListNode node = nodeMap.get(key);
            moveToHead(node);
            Set<ListNode> set = expireMap.get(node.expire);
            set.remove(node);
            node.expire = expire+System.currentTimeMillis();
            if(!expireMap.containsKey(node.expire)){
                set = new HashSet<>();
                set.add(node);
                queue.offer(node.expire);
                expireMap.put(node.expire,set);
            }
            else{
                set = expireMap.get(node.expire);
                set.add(node);
            }
            return;
        }
        if(size>=capacity){
            ListNode node = tail.pre;
            removeNode(node);
            nodeMap.remove(node.key);
            Set<ListNode> set = expireMap.get(node.expire);
            set.remove(node);
            size--;
        }
        ListNode node = new ListNode(key,value,expire);
        addToHead(node);
        nodeMap.put(node.key,node);
        if(!expireMap.containsKey(node.expire)){
            Set<ListNode> set = new HashSet<>();
            set.add(node);
            expireMap.put(node.expire,set);
            queue.offer(node.expire);
        }
        else{
            Set<ListNode> set= expireMap.get(node.expire);
            set.add(node);
        }
    }

    public void removeByExpire(){
        if(queue.isEmpty())
            return;
        long expire = queue.peek();
        long now = System.currentTimeMillis();
        if(expire<=now){
            Set<ListNode> set = expireMap.get(expire);
            for(ListNode n:set){
                removeNode(n);
                nodeMap.remove(n.key);
                size--;
            }
            expireMap.remove(expire);
            queue.poll();
        }
    }

    public void addToHead(ListNode node){
        node.next = head.next;
        head.next = node;
        node.next.pre = node;
        node.pre = head;
    }

    public void removeNode(ListNode node){
        node.pre.next = node.next;
        node.next.pre = node.pre;
    }

    public void moveToHead(ListNode node){
        removeNode(node);
        addToHead(node);
    }



}

测试代码

public static void main(String[] args) throws InterruptedException {
        int v = 0;
        LRUWithExpire lru = new LRUWithExpire(3);
        lru.put(1,2,3000);
        lru.put(2,3,3000);
        lru.put(3,4,2000);
        v = lru.get(3);
        System.out.println(v);
        Thread.sleep(2000);
        lru.put(4,5,2000);
        v = lru.get(1);
        System.out.println(v);
        v = lru.get(3);
        System.out.println(v);
        Thread.sleep(1000);
        System.out.println(lru.get(1));
        System.out.println(lru.get(2));
        System.out.println(lru.get(4));
    }

结果

4
2
-1
-1
-1
5

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值