java实现简单的LRU Cache

本文介绍了两种实现LRU缓存的方法:一种是通过记录每个键值对的访问时间进行淘汰,但效率较低;另一种使用双向链表维护访问顺序,提高了效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目来源https://oj.leetcode.com/problems/lru-cache/


我第一次的实现思路是为每个键值对记录下访问时间,然后删除时遍历访问时间来删除,显然这样的效率不高

public class LRUCache {
    
    private int cap;
    private HashMap<Integer,Integer> map = new HashMap<Integer,Integer>();
    private HashMap<Integer,Long> tmap = new HashMap<Integer,Long>();
    public LRUCache(int capacity) {
        this.cap = capacity;
    }
    
    public int get(int key) {
        Integer i = map.get(key);
        if(i == null)
            return -1;
        else
        {
            tmap.put(key,System.nanoTime());
            return i;
        }
    }
    
    public void set(int key, int value) {
        map.put(key,value);
        tmap.put(key,System.nanoTime());
        if(map.size() > this.cap)
        {
            long oldvalue = Long.MAX_VALUE;
            int oldkey = -1;
            for(Map.Entry<Integer,Long> en : tmap.entrySet())
            {
                if(en.getValue() < oldvalue)
                {
                    oldvalue = en.getValue();
                    oldkey = en.getKey();
                }
            }
            map.remove(oldkey);
            tmap.remove(oldkey);
        }
    }
}


看了网上的讨论,用双向链表来维护访问的顺序比较好,于是给出下面的实现

class LRUCache {
    
    private int cap;
    private HashMap<Integer,Item> map = new HashMap<Integer,Item>();
    private Item sen;
    public LRUCache(int capacity) {
        this.cap = capacity;
        sen = new Item(null,null);
        sen.pre = sen;
        sen.next = sen;
    }
    static class Item
    {
    	public Item(Integer k, Integer v)
    	{
    		this.key = k;
    		this.value = v;
    	}
    	public Integer key;
    	public Integer value;
    	public Item pre;
    	public Item next;
    	
    }
    private void removeItem(Item i)
    {
    	i.pre.next = i.next;
    	i.next.pre = i.pre;
    }
    private void insertItem(Item i)
    {
    	i.next = sen.next;
    	sen.next.pre = i;
    	i.pre = sen;
    	sen.next = i;
    }
    private void movetoHead(Item i)
    {
    	removeItem(i);
    	insertItem(i);
    }
    public int get(int key) {
        Item i = map.get(key);
        if(i == null)
            return -1;
        else
        {
        	movetoHead(i);
            return i.value;
        }
    }
    
    public void set(int key, int value) {
    	Item i = map.get(key);
        if(i == null)
        {
        	i = new Item(key,value);
        	map.put(key, i);
        	insertItem(i);
        }
        else
        {
        	i.value = value;
        	movetoHead(i);
        }
        if(map.size() > this.cap)
        {
        	Item re = sen.pre;
        	removeItem(re);
            map.remove(re.key);
            
        }
    }
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值