• LRU


    一份利用LinkedHashMap实现的简易LRU。注意,LinkedHashMap 继承自 HashMap,get方法直接使用的HashMap提供的。

    public static void main(String[] args) {
            int[][] operators = new int[][] { 
                new int[] { 1, 1, 1 }, 
                new int[] { 1, 2, 2 }, 
                new int[] { 1, 3, 2 },
                new int[] { 2, 1 }, 
                new int[] { 1, 4, 4 }, 
                new int[] { 1, 100, 4 }, 
                new int[] { 2, 3} };
            int[] arr = LRUCache_NowCode.LRU(operators, 4);
            System.out.println(Arrays.toString(arr));
    
        }
    
        public static int[] LRU (int[][] operators, int k) {
            // 声明一个linkedHashMap,容量为k,负载因子为0.75,按照获取顺序排序
            // 也就是说,新加进来的节点,都会在队列的尾部
            // 队列的头部,一定是最近使用最少的那个节点
            LinkedHashMap<Integer,Integer> lru = new LinkedHashMap<Integer,Integer>(k,0.75f,true);
            List<Integer> list = new ArrayList<Integer>();
            for(int[] ope : operators){
                int tmp = ope[0];
                int key = ope[1];
                //增加缓存
                if(tmp == 1){
                    //如果已经存在key,则直接删除旧值
                    if(lru.containsKey(key)){
                        lru.remove(key);
                    }else if(lru.size() >= k){
                        //如果容量已经满了,则删除排在队列第一个的元素
                        lru.remove(lru.keySet().iterator().next());
                    }
                    //将新的数据加在队列的尾部
                    lru.put(key,ope[2]);
                }else if(tmp == 2){
                    //获取缓存值
                    if(lru.containsKey(key)){
                        // 直接调用的hashMap中的值进行处理
                        int value = lru.get(key);
                        //移除旧值
                        lru.remove(key);
                        //增加新值
                        lru.put(key,value);
                        //拿到结果并保存
                        list.add(value);
                    }else {
                        list.add(-1);
                    }
                }
                printLinkMap(lru);
            }
            int[] res = new int[list.size()];
            for(int i = 0; i < res.length; i++){
                res[i] = list.get(i);
            }
            return res;
        }
    
        public LRUCache_NowCode(int k) {
            this.size = k;
        }
    
        private int size = -1; // 容量
        
        public static void printLinkMap(LinkedHashMap<Integer,Integer> lru) {
            Iterator<Integer> iter = lru.keySet().iterator();
            while(iter != null && iter.hasNext()) {
                System.out.print(" v ->" + iter.next());
            }
            System.out.println();
        }

    一份利用hashMap实现的LRU

    node类

    class Node{
        private int v;
        
        private Object  k;
        private Node next;
        private Node pre;
        
        public Node(Object key,int value) {
            this.v = value;
            this.k = key;
        }
        
        public int getV() {
            return v;
        }
        public void setV(int v) {
            this.v = v;
        }
        public Node getNext() {
            return next;
        }
        public void setNext(Node next) {
            this.next = next;
        }
        public Node getPre() {
            return pre;
        }
        public void setPre(Node pre) {
            this.pre = pre;
        }
    
        public Object getK() {
            return k;
        }
    
        public void setK(Object k) {
            this.k = k;
        }
    }

    LRUcache类

    public class LRUCache_NowCode {
        public static Object[] LRU(int[][] operators, int k) {
            if (operators.length <= 0 || k <= 0) {
                return null;
            }
            List<Object> reList = new ArrayList<Object>();
            LRUCache_NowCode cache = new LRUCache_NowCode(k);
            for (int[] tmpArr : operators) {
                int key = tmpArr[0];
                switch (key) {
                case 1:
                    cache.set(Integer.valueOf(tmpArr[1]), Integer.valueOf(tmpArr[2]));
                    break;
                case 2:
                    reList.add(cache.get(Integer.valueOf(tmpArr[1])));
                    break;
                default:
                    break;
                }
            }
            Object[] reArr = new Object[reList.size()];
            for (int i = 0; i < reList.size(); i++) {
                reArr[i] = reList.get(i);
            }
            return reArr;
        }
    
        public LRUCache_NowCode(int k) {
            this.size = k;
        }
    
        private int size = -1; // 容量
    
        private Node head = null;
        private Node tail = null;
    
        private Map<Object, Node> cacheMap = new HashMap<Object, Node>();
    
        public void set(Object key, int value) {
            System.out.println("set key -> " + key + " value -> " + value);
            Node node = cacheMap.get(key);
            if (node == null) {
                node = new Node(key,value);
                cacheMap.put(key, node);
            } else {
                // 将节点从链表中移除
                if (node.getNext() != null) {
                    node.getNext().setPre(node.getPre());
                }
                if (node.getPre() != null) {
                    node.getPre().setNext(node.getNext());
                }
                node.setV(value);
            }
            // 头尾节点给默认值
            if (head == null || tail == null) {
                head = tail = node;
            }
            // 容量判断
            if (cacheMap.size() > size) {
                //移除尾指针
                cacheMap.remove(tail.getK());
                //移动尾指针
                tail = tail.getPre();
           if(tail != null) tail.setNext(
    null); } // 当前节点不是头结点 if (head != node) { head.setPre(node); node.setNext(head); node.setPre(null); head = node; } printHead(head); printTail(tail); System.out.println("-----"); } public static void printHead(Node node) { System.out.print(node.getV()); Node tmp = node; while (tmp.getNext() != null) { tmp = tmp.getNext(); System.out.print(" next -> " + tmp.getV()); } System.out.println(); } public static void printTail(Node node) { System.out.print(node.getV()); Node tmp = node; while (tmp.getPre() != null) { tmp = tmp.getPre(); System.out.print(" pre -> " + tmp.getV()); } System.out.println(); } /** * 移到队列头部 * * @param i * @return */ public Object get(Object key) { System.out.println("get key -> " + key); Node existNode = cacheMap.get(key); if (existNode == null) { return -1; } Node n = existNode.getNext(); Node p = existNode.getPre(); if (p != null) { p.setNext(n); } if (n != null) { n.setPre(p); } existNode.setNext(head); head.setPre(existNode); existNode.setPre(null); head = existNode; // 如果恰好查的是尾节点,那将尾指针前移一个单位 if (tail == existNode) { tail = p; tail.setNext(null); } return existNode.getV(); } }

    main方法测试

    public static void main(String[] args) {
            int[][] operators = new int[][] { 
            new int[] { 1, 1, 1 }, 
            new int[] { 1, 2, 2 }, 
            new int[] { 1, 3, 2 },
        new int[] { 2, 1 }, 
            new int[] { 1, 4, 4 }, 
            new int[] { 2, 2 } };
        Object[] arr = LRUCache_NowCode.LRU(operators, 3);
        System.out.println(Arrays.toString(arr));
        }        

    此处直接将key保存在了对象中,可以根据对象之间的引用关系直接找到前后的key,简化处理头尾节点时逻辑。

  • 相关阅读:
    Golang冒泡排序
    排序算法
    【pdf】PHP基础完整
    【day04】PHP
    【day03】php
    【pdf】XHTML——CSS笔记整理
    【pdf】XHTML&CSS
    【day05】css
    【day06】css
    【day04】css
  • 原文地址:https://www.cnblogs.com/brave-rocker/p/14018486.html
Copyright © 2020-2023  润新知