LRU 实现缓存
Posted zhy-study
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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;} }
以上是关于LRU 实现缓存的主要内容,如果未能解决你的问题,请参考以下文章