面试题:手写LRU缓存

题目:手写实现一个LRU缓存,支持get() put()

思路
1.可以使用最基础的单向链表处理
2.使用双向链表,可以加入hash表做优化
3.最简单的实现是使用JDK中自带的LinkedHashMap,需要重写removeEldestEntry()方法,这是LinkedHashMap提供的一个删除最老条目的方法;

    Map<String,String> map = new LinkedHashMap<>(size, 0.75F,true) //false:基于插入排序,true:基于访问排序
1.基于双向链表的实现:
class LRUNode{
    private String key;
    private String value;
    private LRUNode pre;
    private LRUNode next;

    public LRUNode(String key, String value) {
        this.key = key;
        this.value = value;
    }
}


private volatile LRUNode head;
private volatile Integer lenght = 0;

public LRUcache(Integer lenght){
    this.lenght = lenght;
}

public  boolean put(String key,String value){

    LRUNode cur = this.head;
    Integer curLenght = 1;
    while (null != cur && cur.next != null){
        curLenght++;
        if(cur.key.equals(key)){
            //包含 修改其前后node的指向
            cur.pre.next = cur.next;
            cur.next.pre = cur.pre;

            cur.pre = null;
            cur.next = head;
            head.pre = cur;
            return true;
        }else {
            cur = cur.next;
        }
    }
    //没有找到
    LRUNode newNode = new LRUNode(key,value);
    if(curLenght >= lenght){
        //删除最后一个对象
        cur.pre.next = null;
        cur.pre = null;
        newNode.next = head;
        head.pre = newNode;

    }else{
        if(head != null){
            head.pre = newNode;
            newNode.next = head;
        }
    }
    head = newNode;
    return true;
}

public LRUNode get(String key){
    if(key.isEmpty()){
        throw new RuntimeException("key not is find");
    }
    LRUNode cur = head;
    while (lenght != 0 && cur != null){
        if(cur.key.equals(key)){
            if(null != cur.pre && null != cur.next){
                cur.pre.next = cur.next;
                cur.next.pre = cur.pre;

            }else if(null != cur.pre){
                cur.pre.next = null;
            }

            cur.pre = null;
            cur.next = head;
            head.pre = cur;
            head = cur;
            return cur;
        }
        cur = cur.next;
    }
    throw new NullPointerException("this key not find");
}
2.基于LinkedHashMap
private volatile Map<String,String> lruMap;
private int cacheSize;

public LRUcache(int initSize){
    this.cacheSize = initSize;
    this.lruMap = new LinkedHashMap<String,String>(initSize,0.75f,true){
        @Override
        protected boolean removeEldestEntry(Map.Entry eldest) {
        //size()获取map中当前元素数量,和初始设置的值做比较
        //超过预设则删除 eldest(年龄最大的)
            return size() > LRUcache.this.cacheSize;
        }
    };
}

public String get(String inKey){
    if(inKey.isEmpty() || this.lruMap.isEmpty()){
        return null;
    }
    for(String key : lruMap.keySet()){
        if(key.equals(inKey)){
            return lruMap.get(key);
        }
    }
    return null;
}

public synchronized boolean put(String key,String value){
    this.lruMap.put(key,value);
    return true;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值