使用LinkedList的Java LRU缓存

使用LinkedList的Java LRU缓存,java,caching,lru,Java,Caching,Lru,新的堆栈溢出,所以请不要介意我的noob方式问这个问题。我正在尝试使用链表实现LRU缓存,我在这里看到了其他使用linkedHashMap和其他数据结构的实现,但在本例中,我正在尝试使用链表创建最佳优化版本,正如在技术回合中所要求的那样 我已经将这里的缓存大小限制为3 有没有办法更好地优化此LRU实现 这个实现的时间复杂度是多少?如果不考虑只在linkedList中打印值的for循环,它的顺序是否为O(N) public class LRU { public static void ma

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

我已经将这里的缓存大小限制为3

  • 有没有办法更好地优化此LRU实现
  • 这个实现的时间复杂度是多少?如果不考虑只在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));
            }
        }
    }
    
    公共类LRU{
    公共静态void main(字符串[]args){
    LinkedList=新建LinkedList();
    int[]feed={7,0,1,2,0,3,0,4,2,3,0,3,2,1,2,0,1,7,0,1};
    对于(int i=0;i
  • 我会用

    LinkedList<Integer> list = new LinkedList<>();
    
    如果下一个值在列表中,它将被删除并作为列表中的第一个元素

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


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

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

    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(){
            //
        }
    }
    
    类MRU{
    最终整数大小;
    MRU(整数大小){
    这个。大小=大小;
    }
    无效放置(整数值){
    //
    }
    Set mostRecentlyUsed(){
    //
    }
    }
    
    这是我的LRU缓存的linkedlist impl,它无法通过leetcode判断,因为linkedlist花费的时间太长(您将超过时间限制)

    公共类LRUCache{
    私有映射块=新的HashMap();
    私有LinkedList bru=新LinkedList();
    私人int能力;
    私有整数长度;
    公共LRUCache(内部容量){
    这个。容量=容量;
    这个长度=0;
    }
    公共整数获取(整数密钥){
    整数值=blocks.get(key);
    if(值!=null){
    bru.remove(值);
    bru.addFirst(值);
    返回值;
    }
    返回-1;
    }
    公共无效集(int键,int值){
    if(块。容器(键)){
    bru.remove(blocks.get(key));
    块。put(键、值);
    }否则{
    如果(长度>=容量){
    blocks.remove(bru.removeLast());
    长度--;
    }
    长度++;
    块。put(键、值);
    }
    bru.addFirst(值);
    }
    }
    
    您的程序将无法编译,因为有3条相同的语句,如--int value1=(int)list.get(0);--原因:无法从对象强制转换为int--将其更新为--Integer value1=(Integer)list.get(0)@NikhilJoshi所以我更新了对Integer的更改,但是程序仍然不会在mac上编译,因为它给出了错误“注意:LRU.java使用未检查的或不安全的操作。注意:使用-Xlint重新编译:未检查的详细信息。”但是代码在eclipse IDE上运行正常这些不是编译错误,而是警告。它告诉你你的代码闻起来很难闻,但编译器还是会处理它。您可以通过执行
    LinkedList=new LinkedList()来摆脱这些问题
    (查找Java泛型的含义)@tmax,SJuan76 LinkedList声明仅在您使用Java-7时有效。否则使用--LinkedList=new LinkedList();您的代码没有设计缓存对象,它描述了一个过程。什么是缓存对象?它的方法是什么?旁注:您的实现看起来可以使用堆栈语义,幸运的是,LinkedList是某种堆栈实现
    class MRU {
        final int size;
        MRU(int size){
            this.size = size;
        }
    
        void put(Integer value){
            //
        }
    
        Set<Integer> mostRecentlyUsed(){
            //
        }
    }
    
    public class 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);
        }
    }