# 缓存淘汰算法--LRU算法(java代码实现)

LRU

LRU（Least recently used，最近最少使用）算法根据数据的历史访问记录来进行淘汰数据，其核心思想是“如果数据最近被访问过，那么将来被访问的几率也更高”。

1. 新数据插入到链表头部；
2. 每当缓存命中（即缓存数据被访问），则将数据移到链表头部；
3. 当链表满的时候，将链表尾部的数据丢弃。

【命中率】

【复杂度】

【代价】

import java.util.ArrayList;
import java.util.Collection;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.Map;

/**
*
* @author dennis
*
* @param <K>
* @param <V>
*/
private final int maxCapacity;

private static final float DEFAULT_LOAD_FACTOR = 0.75f;

private final Lock lock = new ReentrantLock();

this.maxCapacity = maxCapacity;
}

@Override
protected boolean removeEldestEntry(java.util.Map.Entry<K, V> eldest) {
return size() > maxCapacity;
}
@Override
public boolean containsKey(Object key) {
try {
lock.lock();
return super.containsKey(key);
} finally {
lock.unlock();
}
}

@Override
public V get(Object key) {
try {
lock.lock();
return super.get(key);
} finally {
lock.unlock();
}
}

@Override
public V put(K key, V value) {
try {
lock.lock();
return super.put(key, value);
} finally {
lock.unlock();
}
}

public int size() {
try {
lock.lock();
return super.size();
} finally {
lock.unlock();
}
}

public void clear() {
try {
lock.lock();
super.clear();
} finally {
lock.unlock();
}
}

public Collection<Map.Entry<K, V>> getAll() {
try {
lock.lock();
return new ArrayList<Map.Entry<K, V>>(super.entrySet());
} finally {
lock.unlock();
}
}
}  

LRUCache的链表+HashMap实现

import java.util.HashMap;
import java.util.Map.Entry;
import java.util.Set;

public class LRUCache<K, V> {

private int currentCacheSize;
private int CacheCapcity;
private HashMap<K,CacheNode> caches;
private CacheNode first;
private CacheNode last;

public LRUCache(int size){
currentCacheSize = 0;
this.CacheCapcity = size;
caches = new HashMap<K,CacheNode>(size);
}

public void put(K k,V v){
CacheNode node = caches.get(k);
if(node == null){
if(caches.size() >= CacheCapcity){

caches.remove(last.key);
removeLast();
}
node = new CacheNode();
node.key = k;
}
node.value = v;
moveToFirst(node);
caches.put(k, node);
}

public Object  get(K k){
CacheNode node = caches.get(k);
if(node == null){
return null;
}
moveToFirst(node);
return node.value;
}

public Object remove(K k){
CacheNode node = caches.get(k);
if(node != null){
if(node.pre != null){
node.pre.next=node.next;
}
if(node.next != null){
node.next.pre=node.pre;
}
if(node == first){
first = node.next;
}
if(node == last){
last = node.pre;
}
}

return caches.remove(k);
}

public void clear(){
first = null;
last = null;
caches.clear();
}

private void moveToFirst(CacheNode node){
if(first == node){
return;
}
if(node.next != null){
node.next.pre = node.pre;
}
if(node.pre != null){
node.pre.next = node.next;
}
if(node == last){
last= last.pre;
}
if(first == null || last == null){
first = last = node;
return;
}

node.next=first;
first.pre = node;
first = node;
first.pre=null;

}

private void removeLast(){
if(last != null){
last = last.pre;
if(last == null){
first = null;
}else{
last.next = null;
}
}
}
@Override
public String toString(){
StringBuilder sb = new StringBuilder();
CacheNode node = first;
while(node != null){
sb.append(String.format("%s:%s ", node.key,node.value));
node = node.next;
}

return sb.toString();
}

class CacheNode{
CacheNode pre;
CacheNode next;
Object key;
Object value;
public CacheNode(){

}
}

public static void main(String[] args) {

LRUCache<Integer,String> lru = new LRUCache<Integer,String>(3);

lru.put(1, "a");    // 1:a
System.out.println(lru.toString());
lru.put(2, "b");    // 2:b 1:a
System.out.println(lru.toString());
lru.put(3, "c");    // 3:c 2:b 1:a
System.out.println(lru.toString());
lru.put(4, "d");    // 4:d 3:c 2:b
System.out.println(lru.toString());
lru.put(1, "aa");   // 1:aa 4:d 3:c
System.out.println(lru.toString());
lru.put(2, "bb");   // 2:bb 1:aa 4:d
System.out.println(lru.toString());
lru.put(5, "e");    // 5:e 2:bb 1:aa
System.out.println(lru.toString());
lru.get(1);         // 1:aa 5:e 2:bb
System.out.println(lru.toString());
lru.remove(11);     // 1:aa 5:e 2:bb
System.out.println(lru.toString());
lru.remove(1);      //5:e 2:bb
System.out.println(lru.toString());
lru.put(1, "aaa");  //1:aaa 5:e 2:bb
System.out.println(lru.toString());
}

}


©️2019 CSDN 皮肤主题: 大白 设计师: CSDN官方博客