zoukankan      html  css  js  c++  java
  • LRU算法

    LRU

    目的:创建了一个哈希表作为缓存,每次查找一个用户的时候先在哈希表中查询,以此提高访问性能

    LRU 全称 Least Recently Used,也就 是最近最少使用的意思,是一种内存菅理算法,最早应用于Linux操作系统

    LRU算法基于一种假设:长期不被使用的数据,在未来被用到的几率也不大。

    因此.当数据所占内存达到一定阈值吋, 我们要移除掉最近最少被使用的数据。

    代码:

    import java.io.*;
    import java.util.*;
    
    class test  
    {
        public static void main (String[] args) throws java.lang.Exception
        {
            LRUCache lruCache = new LRUCache(5);
            lruCache.put("001", "用户1信息");
            lruCache.put("002", "用户2信息");
            lruCache.put("003", "用户3信息");
            lruCache.put("004", "用户4信息");
            lruCache.put("005", "用户5信息");
            
            System.out.println("原始序列 : ");
            lruCache.viewAllNode();//原始序列
            
            lruCache.get("002");//更新002之后,002位置提前了
            
            System.out.println("更新002之后 : ");
            lruCache.viewAllNode();
            
            lruCache.put("004", "用户4信息更新");//更新004之后,004位置提前了
            System.out.println("更新004之后 : ");
            lruCache.viewAllNode();
            
            System.out.println("插入006之后 : ");
            lruCache.put("006", "用户6信息");//插入新的值,001被挤掉了
            lruCache.viewAllNode();
            
        }
    }
    
    class LRUCache{
        
        private Node head;
        private Node end;
        
        //缓存存储上限
        private int limit;
        private HashMap<String, Node> hashMap;
        
        public LRUCache(int limit) {
            this.limit = limit;
            hashMap = new HashMap<String, Node>();
        }
        
        public String getFirstNode(){
            if(head != null){
                return head.value;
            }else{
                return null;
            }
        }
        
        public String getEndNode(){
            if(end != null){
                return end.value;
            }else{
                return null;
            }
        }
        
        public void viewAllNode(){
            if(head != null){
                System.out.print(head.value);
                Node temp = head.next;
                while(temp != null){
                    System.out.print(" - " + temp.value);
                    temp = temp.next;
                }
                System.out.println("");
            }
        }
        
        public String get(String key) {
            Node node = hashMap.get(key);
            if (node == null){
                return null;
            }
            refreshNode(node);
            return node.value;
        }
        
        public void put(String key, String value) {
            Node node = hashMap.get(key);
            if (node == null) {
                //如果key不存在,插入key-value
                if (hashMap.size() >= limit) {
                    String oldKey = removeNode(head);
                    hashMap.remove(oldKey);
                }
                node = new Node(key, value);
                addNode(node);
                hashMap.put(key, node);
            }else {
                //如果key存在,刷新key-value
                node.value = value;
                refreshNode(node);
            }
        }
        
        public void remove(String key) {
            Node node = hashMap.get(key);
            removeNode(node);
            hashMap.remove(key);
        }
        
        /** 
         * 刷新被访问的节点位置 
         * @param  node 被访问的节点 
         */
        private void refreshNode(Node node) {
            //如果访问的是尾节点,无需移动节点
            if (node == end) {
                return;
            }
            //移除节点
            removeNode(node);
            //重新插入节点
            addNode(node);
        }
        
        /**
         * 删除节点 
         * @param  node 要删除的节点 
         */
        private String removeNode(Node node) {
            if (node == end) {
                //移除尾节点
                end = end.pre;
            }else if(node == head){
                //移除头节点
                head = head.next;
            } else {
                //移除中间节点
                node.pre.next = node.next;
                node.next.pre = node.pre;
            }
            return node.key;
        }
        
        /**
         * 尾部插入节点
         * @param  node 要插入的节点 
         */
        private void addNode(Node node) {
            if(end != null) {
                end.next = node;
                node.pre = end;
                node.next = null;
            }
            end = node;
            if(head == null){
                head = node;
            }
        }
        
    }
    
    
    class Node {
        Node(String key, String value){
            this.key = key;
            this.value = value;
        }
        public Node pre;
        public Node next;
        public String key;
        public String value;
    }

    下面加上 synchronized 解决进程安全问题

    import java.io.*;
    import java.util.*;
    
    class test  
    {
        public static void main (String[] args) throws java.lang.Exception
        {
            LRUCache lruCache = new LRUCache(5);
            lruCache.put("001", "用户1信息");
            lruCache.put("002", "用户2信息");
            lruCache.put("003", "用户3信息");
            lruCache.put("004", "用户4信息");
            lruCache.put("005", "用户5信息");
            
            System.out.println("原始序列 : ");
            lruCache.viewAllNode();//原始序列
            
            lruCache.get("002");//更新002之后,002位置提前了
            
            System.out.println("更新002之后 : ");
            lruCache.viewAllNode();
            
            lruCache.put("004", "用户4信息更新");//更新004之后,004位置提前了
            System.out.println("更新004之后 : ");
            lruCache.viewAllNode();
            
            System.out.println("插入006之后 : ");
            lruCache.put("006", "用户6信息");//插入新的值,001被挤掉了
            lruCache.viewAllNode();
            
        }
    }
    
    class LRUCache{
        
        private Node head;
        private Node end;
        
        //缓存存储上限
        private int limit;
        private HashMap<String, Node> hashMap;
        
        public LRUCache(int limit) {
            this.limit = limit;
            hashMap = new HashMap<String, Node>();
        }
        
        public String getFirstNode(){
            if(head != null){
                return head.value;
            }else{
                return null;
            }
        }
        
        public String getEndNode(){
            if(end != null){
                return end.value;
            }else{
                return null;
            }
        }
        
        public void viewAllNode(){
            if(head != null){
                System.out.print(head.value);
                Node temp = head.next;
                while(temp != null){
                    System.out.print(" - " + temp.value);
                    temp = temp.next;
                }
                System.out.println("");
            }
        }
        
        public synchronized String get(String key) {
            
            try {
                
                Node node = hashMap.get(key);
                if (node == null){
                    return null;
                }
                
                refreshNode(node);
                return node.value;
                
            } catch (Exception e) {
                e.printStackTrace();
            }
            return "";
        }
        
        public synchronized void put(String key, String value) {
            
            try {
                
                Node node = hashMap.get(key);
                if (node == null) {
                    //如果key不存在,插入key-value
                    if (hashMap.size() >= limit) {
                        String oldKey = removeNode(head);
                        hashMap.remove(oldKey);
                    }
                    node = new Node(key, value);
                    addNode(node);
                    hashMap.put(key, node);
                }else {
                    //如果key存在,刷新key-value
                    node.value = value;
                    refreshNode(node);
                }
                
            } catch (Exception e) {
                e.printStackTrace();
            }
            
        }
        
        public void remove(String key) {
            Node node = hashMap.get(key);
            removeNode(node);
            hashMap.remove(key);
        }
        
        /** 
         * 刷新被访问的节点位置 
         * @param  node 被访问的节点 
         */
        private void refreshNode(Node node) {
            //如果访问的是尾节点,无需移动节点
            if (node == end) {
                return;
            }
            //移除节点
            removeNode(node);
            //重新插入节点
            addNode(node);
        }
        
        /**
         * 删除节点 
         * @param  node 要删除的节点 
         */
        private String removeNode(Node node) {
            if (node == end) {
                //移除尾节点
                end = end.pre;
            }else if(node == head){
                //移除头节点
                head = head.next;
            } else {
                //移除中间节点
                node.pre.next = node.next;
                node.next.pre = node.pre;
            }
            return node.key;
        }
        
        /**
         * 尾部插入节点
         * @param  node 要插入的节点 
         */
        private void addNode(Node node) {
            if(end != null) {
                end.next = node;
                node.pre = end;
                node.next = null;
            }
            end = node;
            if(head == null){
                head = node;
            }
        }
        
    }
    
    
    class Node {
        Node(String key, String value){
            this.key = key;
            this.value = value;
        }
        public Node pre;
        public Node next;
        public String key;
        public String value;
    }

    输出:

    原始序列 : 
    用户1信息 - 用户2信息 - 用户3信息 - 用户4信息 - 用户5信息
    更新002之后 : 
    用户1信息 - 用户3信息 - 用户4信息 - 用户5信息 - 用户2信息
    更新004之后 : 
    用户1信息 - 用户3信息 - 用户5信息 - 用户2信息 - 用户4信息更新
    插入006之后 : 
    用户3信息 - 用户5信息 - 用户2信息 - 用户4信息更新 - 用户6信息
  • 相关阅读:
    UVA1349 Optimal Bus Route Design 最优巴士路线设计
    POJ3565 Ants 蚂蚁(NEERC 2008)
    UVA1663 Purifying Machine 净化器
    UVa11996 Jewel Magic 魔法珠宝
    NEERC2003 Jurassic Remains 侏罗纪
    UVA11895 Honorary Tickets
    gdb调试coredump(使用篇)
    使用 MegaCLI 检测磁盘状态并更换磁盘
    员工直接坦诚直来直去 真性情
    山东浪潮超越3B4000申泰RM5120-L
  • 原文地址:https://www.cnblogs.com/lyc94620/p/9957142.html
Copyright © 2011-2022 走看看