zoukankan      html  css  js  c++  java
  • LRU 实现缓存

    LRU:Least Recently used 最近最少使用

    1.使用LinkedHashMap实现 inheritance实现方式 继承map类 可以使用Collections.synchronizedMap方式实现线程安全的操作

    public class LruCache<K,V> extends LinkedHashMap<K,V> {
        private final int MAX_CACHE_SIZE;
        public LruCache(int cacheSize) {
            super((int)Math.ceil(cacheSize/0.75)+1,0.75f,true );
            MAX_CACHE_SIZE = cacheSize;
        }
        @Override
        protected boolean removeEldestEntry(Map.Entry eldest){
            return size()> MAX_CACHE_SIZE;
        }
    
        @Override
        public String toString(){
            StringBuilder sb= new StringBuilder();
            for(Map.Entry<K,V> entry : entrySet()){
                sb.append(String.format("%s:%s",entry.getKey(),entry.getValue()));
            }
            return sb.toString();
        }
    }

    2、LinkedHashMap 使用delegation方式实现

    没有map接口 

    public class LruByDelegation<K,V> {
    
        private final int MAX_CACHE_SIZE;
        private final float DEFAULT_LOAD_FACTOR = 0.75f;
        LinkedHashMap<K,V> map;
    
        public LruByDelegation(int cacheSize) {
            this.MAX_CACHE_SIZE = cacheSize;
    
            int capacity = (int) (Math.ceil(MAX_CACHE_SIZE/DEFAULT_LOAD_FACTOR)+1);
            map= new LinkedHashMap(capacity,DEFAULT_LOAD_FACTOR,true){
                @Override
                protected boolean removeEldestEntry(Map.Entry eldest){
                    return size()>MAX_CACHE_SIZE;
                }
            };
        }
    
        public synchronized void put(K key,V value){
            map.put(key,value);
        }
    
        public synchronized V get(K key){
            return map.get(key);
        }
        public synchronized void remove(K key){
            map.remove(key);
        }
        public synchronized Set<Map.Entry<K,V>> getAll(){
            return map.entrySet();
        }
        public synchronized int size(){
            return map.size();
        }
        public synchronized void clear(){
            map.clear();
        }
    
        @Override
        public String toString(){
            StringBuilder sb= new StringBuilder();
            for(Map.Entry entry : map.entrySet()){
                sb.append(String.format("%s:%s",entry.getKey(),entry.getValue()));
            }
            return sb.toString();
        }
    
    }

    2 Cache链表+HashMap实现   Entry自己定义  总结一下就是各种pre 和 next指针的变换

    public class LruCache01<K,V> {
        private final int MAX_CACHE_SIZE;
        private Entry first;
        private Entry last;
        private HashMap<K, Entry<K,V>> hashMap;
    
        public LruCache01(int MAX_CACHE_SIZE) {
            this.MAX_CACHE_SIZE = MAX_CACHE_SIZE;
            hashMap=new HashMap<>();
        }
        public void put(K key, V value){
            Entry entry = getEntry(key);
            if(entry==null){
                if(hashMap.size()>=MAX_CACHE_SIZE){
                    hashMap.remove(last.key);
                    //removeLast
                    removeLast();
                }
                entry=new Entry();
                entry.key=key;
            }
            entry.value=value;
            moveToFirst(entry);
            hashMap.put(key,entry);
    
        }
        public V get(K  key){
            Entry entry  = getEntry(key);
            if(entry==null)
                return null;
            moveToFirst(entry);
            return (V) entry.value;
        }
    
        public void remove(K key){
            Entry entry = getEntry(key);
            if(entry!=null){
                if(entry.pre!=null)
                    entry.pre.next=entry.next;
                if(entry.next!=null)
                    entry.next.pre=entry.pre;
                if(entry==first)
                    first=entry.next;
                if(entry==last)
                    last=entry.pre;
            }
            hashMap.remove(key);
        }
        public void moveToFirst(Entry entry){
            if(entry==first)
                return;
            if(entry.pre!=null)
                entry.pre.next=entry.next;
            if(entry.next!=null)
                entry.next.pre=entry.pre;
            if(entry==last)
                last=last.pre;
            if(first==null || last==null){
                first=last=entry;
                return;
            }
            entry.next=first;
            first.pre=entry;
            first=entry;
            entry.pre=null;
        }
    
    
        public void removeLast(){
            if(last!=null){
                last=last.pre;
                if(last==null)
                    first=null;
                else
                    last.next=null;
            }
        }
    
        public Entry<K,V> getEntry(K key){
            return hashMap.get(key);
        }
    
        @Override
        public String toString(){
            StringBuilder sb= new StringBuilder();
            Entry entry = first;
            while(entry!=null){
                sb.append(String.format("%s:%s",entry.key,entry.value));
                entry=entry.next;
            }
            return sb.toString();
        }
    }
    class Entry<K,V>{
        public Entry pre;
        public Entry next;
        public K key;
        public V value;
    }

    LinkedHashMap的FIFO实现

    只需要重新removeEldestEntry方法可以实现FIFO缓存

    final int cacheSize=5;
    LinkedHashMap<Integer,String> lru = new LinkedHashMap<Integer,String>(){
      @Override
    protected boolean removeEldestEntry(Map.Entry<Integer,String> eldest){
    return size()>cacheSize;}  
    }
  • 相关阅读:
    洛谷-P5357-【模板】AC自动机(二次加强版)
    洛谷-P3796-【模板】AC自动机(加强版)
    洛谷-P3808-【模板】AC自动机(简单版)
    2020 CCPC Wannafly Winter Camp Day2-K-破忒头的匿名信
    zabbix的搭建
    playbook 介绍
    ansible 模块
    shell 脚本判断ip
    shell 脚本安装lnmp
    expect 介绍
  • 原文地址:https://www.cnblogs.com/zhy-study/p/9498560.html
Copyright © 2011-2022 走看看