LinkedHashMap是比HashMap多了一個鏈表的結(jié)構(gòu)。與HashMap相比LinkedHashMap維護的是一個具有雙重鏈表的HashMap,LinkedHashMap支持2中排序一種是插入排序,即插入是什么順序,讀出來的就是什么順序。一種是使用排序墩邀,最近使用的會移至尾部例如 key1 key2 key3 key4,使用key3后為 key1 key2 key4 key3了盏浙。accessOrder為true表示使用順序眉睹,false表示插入順序。
基于LinkedHashMap的使用順序的特性废膘,我們可以用來實現(xiàn)LRU算法(Mybatis的LRU算法也是這樣實現(xiàn)的)
bigSize表示緩存最大容量竹海,超過這個值最近最少使用的key,將會被移除殖卑。
public class LruCache extends LinkedHashMap<Object, Object> {
private int bigSize;
public LruCache(int bigSize) {
this(1024, 0.75F, true,8);
}
public LruCache(int initialCapacity, float loadFactor, boolean accessOrder , int bigSize) {
super(initialCapacity, loadFactor, accessOrder);
this.bigSize=bigSize;
}
@Override
protected boolean removeEldestEntry(Map.Entry<Object, Object> eldest) {
boolean toBig=size() > bigSize;
if (toBig){
System.out.println("移除:"+eldest.getKey());
}
return toBig;
}
}
測試
public class Main {
public static void main(String[] args) {
LruCache lruCache = new LruCache(8);
//先插入8個值
for (int i = 0; i < 8; i++) {
lruCache.put("key" +i , ""+i);
}
System.out.println(lruCache.toString());
//操作前3個值
for (int i = 0; i < 3; i++) {
lruCache.put("key" +i , ""+i);
}
System.out.println(lruCache.toString());
//當map中的值超過bigSize
for (int i = 9; i < 11; i++) {
lruCache.put("key" +i , ""+i);
}
System.out.println(lruCache.toString());
}
}
結(jié)果如下,當我們重新訪問前3個值后站削,他們會被放到鏈表最后坊萝。前面的值會被移除孵稽。
{key0=0, key1=1, key2=2, key3=3, key4=4, key5=5, key6=6, key7=7}
{key3=3, key4=4, key5=5, key6=6, key7=7, key0=0, key1=1, key2=2}
移除:key3
移除:key4
{key5=5, key6=6, key7=7, key0=0, key1=1, key2=2, key9=9, key10=10}