使用LinkedList的Java LRU缓存

时间:2014-07-31 09:20:31

标签: java caching lru

堆栈溢出新的所以请不要介意我的noob方式问这个。我尝试使用链表实现LRU缓存,我在这里看到了使用linkedHashMap和其他数据结构的其他实现,但是对于这种情况,我尝试使用链表创建最佳优化版本在技​​术回合中我被问到了。

我已将此处的缓存大小限制为3

  1. 有没有办法更好地优化这个LRU实现?
  2. 此实施的时间复杂度是多少?如果没有考虑只是在linkedList中打印值的for循环,它会是O(N)的顺序吗?

    public class LRU {
        public static void main(String[] args) {
    
            LinkedList list = new LinkedList();
            int[] feed = { 7, 0, 1, 2, 0, 3, 0, 4, 2, 3, 0, 3, 2, 1, 2, 0, 1, 7, 0, 1 };
            for (int i = 0; i < feed.length - 1; i++) {
                if (list.size() <= 2) {
                    list.add(feed[i]);
                    System.out.println();
                    System.out.println("Added " + feed[i]);
                    System.out.println("size of list is " + list.size());
                    System.out.print("this is list ");
                    for (int k = 0; k < list.size(); k++) {
                        System.out.print(" " + list.get(k));
                    }
                }
    
                System.out.println();
                if (list.size() >= 3) {
                    System.out.println();
                    System.out.println("feed is *" + feed[i + 1] + "*");
    
                    Integer value1 = (Integer) list.get(0);
                    Integer value2 = (Integer) list.get(1);
                    Integer value3 = (Integer) list.get(2);
                    if ((feed[i + 1] != value1) || (feed[i + 1] != value2)
                            || (feed[i + 1] != value3)) {
                        list.removeLast();
                        list.addLast(feed[i + 1]);
                        list.set(0, value2);
                        list.set(1, value3);
                        list.set(2, feed[i + 1]);
                    }
                    if (feed[i + 1] == value1) {
                        list.removeLast();
                        list.addLast(value1);
                        list.removeFirst();
                        list.addFirst(value2);
                        list.set(1, value3);
                    }
                    if (feed[i + 1] == value2) {
                        list.removeLast();
                        list.addLast(value2);
                        list.set(1, value3);
                        list.removeFirst();
                        list.addFirst(value1);
                    }
                    if (feed[i + 1] == value3) {
                        list.set(0, value1);
                        list.set(1, value2);
                    }
                }
                System.out.println("Current elements in cache at " + i);
                for (int t = 0; t < list.size(); t++) {
                    System.out.print(" " + list.get(t));
                }
                System.out.println();
            }
            System.out.println();
            System.out.println("------------------------------");
            System.out.println("current elements in cache ");
            for (int i = 0; i < list.size(); i++) {
                System.out.print(" " + list.get(i));
            }
        }
    }
    

3 个答案:

答案 0 :(得分:2)

首先,您要定义一个接口。现在我看不出你应该如何使用你的缓存或事实上你正在做什么。尝试实现以下类:

class LRUCache {
    final int size;
    Cache(int size){
        this.size = size;
    }
    void put(String key, Integer value){
        //
    }
    Integer get(String key){
        //
    }
}

编辑(回复评论):
无论问题是什么,第一步是定义接口(我不是指Java接口,只是传达正在发生的事情的接口)。在你的情况下,尝试实现它。

class MRU {
    final int size;
    MRU(int size){
        this.size = size;
    }

    void put(Integer value){
        //
    }

    Set<Integer> mostRecentlyUsed(){
        //
    }
}

答案 1 :(得分:0)

我用

LinkedList<Integer> list = new LinkedList<>();

而不是你的实现,我会使用

if (list.size() >= 3) {
    System.out.println();
    System.out.println("feed is *" + feed[i + 1] + "*");

    // retrieve the next value from the feed
    Integer next = feed[i + 1];

    if (!list.remove(next)) {
        list.removeLast();
    }
    list.addFirst(next);

}

System.out.println("Current elements in cache at " + i);

如果下一个值在列表中,它将被删除并作为列表中的第一个元素。

如果下一个值不在列表中,则删除最后一个元素,并将下一个值作为列表中的第一个元素。

然后在列表中查找元素时,e。 G。通过indexOf(...),从最新的条目到最旧的条目搜索列表。

答案 2 :(得分:0)

这是我的LRU缓存的链接列表impl,它不会传递leetcode判断,因为链表需要太长时间(你会超时限制)。

公共类LRUCache {

private Map<Integer, Integer> blocks = new HashMap<Integer,Integer>();
private LinkedList<Integer> bru = new LinkedList<Integer>();
private int capacity;
private int length;

public LRUCache(int capacity) {
    this.capacity = capacity;
    this.length = 0;
}

public int get(int key) {
    Integer value = blocks.get(key);
    if (value != null) {
        bru.remove(value);
        bru.addFirst(value);
        return value;
    }
    return -1;
}

public void set(int key, int value) {
    if (blocks.containsKey(key)) {
        bru.remove(blocks.get(key));
        blocks.put(key, value);
    } else {
        if (length >= capacity) {
            blocks.remove(bru.removeLast());
            length--;
        }

        length++;
        blocks.put(key, value);
    }
    bru.addFirst(value);
}

}