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信息
  • 相关阅读:
    LeetCode_21.合并两个有序链表
    LeetCode_70.爬楼梯
    LeetCode_001.两数之和
    LeetCode_509.斐波那契数
    Eclipse(2019-03版本)汉化
    修改Gradle本地仓库
    解决Eclipse导入Gradle项目时在 Building gradle project info 一直卡住
    Eclipse设置字体大小
    @Transactional spring 事务(转载)
    @Transactional spring 事务失效(转载)
  • 原文地址:https://www.cnblogs.com/lyc94620/p/9957142.html
Copyright © 2011-2022 走看看