LinkedHashMap笔记-LRU(least recently used)

本文,只要讲下基于LinkedHashMap来实现LRU结构,了解LRU的实现思路,LinkedHashMap的实现结构,也基本熟悉了。

下面的图转自:http://uule.iteye.com/blog/1522291

LinkedHashMap添加新元素时,调用put方法。
put(K k, V v)->HashMap.put(k, v)->如果是新的k, 即新的map元素->HashMap.addEntry(int hash, K key, V value, int bucketIndex)->LinkedHashMap重写了addEntry方法->
LinkedHashMap.addEntry(hash, k, v, bucketIndex);
 
下面看看LinkedHashMap的addEntry方法:
void addEntry(int hash, K key, V value, int bucketIndex) {
    super.addEntry(hash, key, value, bucketIndex); //1处
 
    // Remove eldest entry if instructed
    Entry<K,V> eldest = header.after;
    if (removeEldestEntry(eldest)) {//2处
        removeEntryForKey(eldest.key);
    }
}
 
看看上面源码的1处,首先会将map元素put进去,源码的2处判断map元素添加了进去,是否需求删去最旧的元素,下面是LinkedHashMap的源码。
protected boolean removeEldestEntry(Map.Entry<K,V> eldest) {
    return false;
}
LinkedHashMap默认是不会删除最老的元素的。
 
从1处,super.addEntry,即是调用的HashMap的addEntry方法,看看HashMap的addEntry源码:
void addEntry(int hash, K key, V value, int bucketIndex) {
    if ((size >= threshold) && (null != table[bucketIndex])) {
        resize(2 * table.length);
        hash = (null != key) ? hash(key) : 0;
        bucketIndex = indexFor(hash, table.length);
    }
 
    createEntry(hash, key, value, bucketIndex); //3处
}
从上面的3处,创建一个新的Entry,LinkedHashMap重写了HashMap的createEntry方法:
void createEntry(int hash, K key, V value, int bucketIndex) {
    HashMap.Entry<K,V> old = table[bucketIndex];
    Entry<K,V> e = new Entry<>(hash, key, value, old);
    table[bucketIndex] = e;
    e.addBefore(header); //4处
    size++;
}
从1处中的header,是LinkedHashMap的链头,LinkedHashMap创建时会初始化header:
void init() {
    header = new Entry<>(-1, null, null, null);
    header.before = header.after = header;
}
下面是LinkedHashMap.Entry的addBefore方法:
private void addBefore(Entry<K,V> existingEntry) {
    after  = existingEntry;
    before = existingEntry.before;
    before.after = this;
    after.before = this;
}


这样可以将新创建的Entry链接到链头head之前,head之后是新创建的Entry,形成了双向链表。
 
所以如果需要自定义LRU map,即是,least recently used(最近最少使用)的功能,则只重写removeEldestEntry(java.util.Map.Entry<K, V> eldest)方法就好了。
一般来说,自定义LRU,会定义好map的size,只要map的元素数量超过这个size,则会删除最老的元素即可,下面是部分代码:
private static class LRUCache<K, V>{
         
    private int cacheSize;
     
    private LinkedHashMap<K, V> linkedHashMap;
     
    public LRUCache(int cacheSize){
        this.cacheSize = cacheSize;
         
        this.linkedHashMap = new LinkedHashMap<K, V>(this.cacheSize, 0.75f, false){
 
            private static final long serialVersionUID = 1L;
             
            @Override
            protected boolean removeEldestEntry(java.util.Map.Entry<K, V> eldest) {
                return size() > LRUCache.this.cacheSize;
            }
        };
    }
 
    //其他的put,get,remove,clear,toString,size方法等
}


其他的方法如put,get等等,调用LinkedHashMap的就可以了。
用LinkedHashMap来实现LRU,主要是基于HashMap的底层结构来保存数据元素。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值