面试题:手写LRU缓存

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

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

    Map 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 lruMap;
private int cacheSize;

public LRUcache(int initSize){
    this.cacheSize = initSize;
    this.lruMap = new LinkedHashMap(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;
}

你可能感兴趣的:(面试题:手写LRU缓存)