LRU实现

使用LinkedHashMap实现LRU

方式一:

import java.util.LinkedHashMap;
import java.util.Map;

public class LRUCache<K,V> extends LinkedHashMap<K,V>{
    private final int CACHE_SIZE;
    
    public LRUCache(int cacheSize) {
        super((int)Math.ceil(cacheSize/0.75), 0.75f, true);
        CACHE_SIZE = cacheSize;
    }
    
    @Override
    protected boolean removeEldestEntry(Map.Entry<K,V> eldest) {
        return size() > CACHE_SIZE;
    }
}

测试:

import java.util.Map;

public class LRUTest {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        LRUCache<Integer, String> lru = new LRUCache<>(10);
        for(int i=0; i<10; i++) {
            lru.put(i, "v="+i);
        }
        
        //最久访问的元素
        for(int i=0; i<10; i++) {
            lru.get(4);
        }
        
        for(int i=0; i<9; i++) {
            lru.get(5);
        }
        
        for(int i=0; i<8; i++) {
            lru.get(6);
        }
        
        for(int i=0; i<7; i++) {
            lru.get(3);
        }
        
        for(int i=0; i<6; i++) {
            lru.get(7);
        }
        for(int i=0; i<5; i++) {
            lru.get(8);
        }
        for(int i=0; i<4; i++) {
            lru.get(9);
        }
        for(int i=0; i<3; i++) {
            lru.get(2);
        }
        for(int i=0; i<2; i++) {
            lru.get(0);
        }
        //最近访问的元素
        for(int i=0; i<2; i++) {
            lru.get(1);
        }
        
        System.out.println("原始");
        for(Map.Entry<Integer, String> entry : lru.entrySet()) {
            System.out.print(entry.getValue() + " ");
        }
        
        lru.put(10,"v="+10);
        
        System.out.println("新增数据");
        for(Map.Entry<Integer, String> entry : lru.entrySet()) {
            System.out.print(entry.getValue() + " ");
        }
    }

}

输出: 

原始
v=4 v=5 v=6 v=3 v=7 v=8 v=9 v=2 v=0 v=1 
新增数据
v=5 v=6 v=3 v=7 v=8 v=9 v=2 v=0 v=1 v=10 

 

方式二:

import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.Map;

public class LRUCache1<K,V> {
    private final int CACHE_SIZE;
    private Map<K,V> cache = null;
    
    public LRUCache1(int cacheSize) {
        CACHE_SIZE = cacheSize;
        cache = Collections.synchronizedMap(new LinkedHashMap<K,V>((int) Math.ceil(cacheSize/0.75), 0.75f, true) {
            /**
             * 
             */
            private static final long serialVersionUID = 1L;

            @Override
            protected boolean removeEldestEntry(Map.Entry<K,V> eldest) {
                return size() > CACHE_SIZE;
            }
        });
        
    }
    
    public void put(K k,V v) {
        cache.put(k, v);
    }
    
    public V get(K k) {
        return cache.get(k);
    }
    
    public String toString() {
        StringBuilder sb = new StringBuilder();
        for(Map.Entry<K, V> entry : cache.entrySet()) {
            sb.append(entry.getValue() + " ");
        }
        return sb.toString();
    }
}

测试:

public class LRUTest1 {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        LRUCache1<Integer, String> lru = new LRUCache1<>(10);
        for(int i=0; i<10; i++) {
            lru.put(i, "v="+i);
        }
        
        //最久访问的元素
        for(int i=0; i<10; i++) {
            lru.get(4);
        }
        
        for(int i=0; i<9; i++) {
            lru.get(5);
        }
        
        for(int i=0; i<8; i++) {
            lru.get(6);
        }
        
        for(int i=0; i<7; i++) {
            lru.get(3);
        }
        
        for(int i=0; i<6; i++) {
            lru.get(7);
        }
        for(int i=0; i<5; i++) {
            lru.get(8);
        }
        for(int i=0; i<4; i++) {
            lru.get(9);
        }
        for(int i=0; i<3; i++) {
            lru.get(2);
        }
        for(int i=0; i<2; i++) {
            lru.get(0);
        }
        //最近访问的元素
        for(int i=0; i<2; i++) {
            lru.get(1);
        }
        
        System.out.println("原始");
        System.out.println(lru.toString());
        
        lru.put(10,"v="+10);
        
        System.out.println("新增数据");
        System.out.println(lru.toString());
    }

}

输出:

原始
v=4 v=5 v=6 v=3 v=7 v=8 v=9 v=2 v=0 v=1 
新增数据
v=5 v=6 v=3 v=7 v=8 v=9 v=2 v=0 v=1 v=10 

 参考:https://juejin.im/post/5dc3a9fbf265da4d3c072eab《我们一起进大厂》系列-Redis哨兵、持久化、主从、手撕LRU

posted @ 2020-05-12 14:51  水木竹水  阅读(217)  评论(0编辑  收藏  举报