LruCache源码解析

作者: zhangxuanchen | 来源:发表于2017-02-11 08:14 被阅读4次

LruCache 内部相当于维护了一个LinkedHashMap

/**
* @param maxSize for caches that do not override {@link #sizeOf}, this is
*     the maximum number of entries in the cache. For all other caches,
*     this is the maximum sum of the sizes of the entries in this cache.
*/
public LruCache(int maxSize) {
        if (maxSize <= 0) {
            throw new IllegalArgumentException("maxSize <= 0");
        }
        this.maxSize = maxSize;
        this.map = new LinkedHashMap<K, V>(0, 0.75f, true);
}

LinkedHashMap 结构为一个双向链表,对照看一下他的构造函数

//双向链表中元素排序规则的标志位。  
//accessOrder为false,表示按插入顺序排序  
//accessOrder为true,表示按访问顺序排序  
private final boolean accessOrder;  

//调用HashMap的构造方法来构造底层的数组  
public LinkedHashMap(int initialCapacity, float loadFactor) {  
   super(initialCapacity, loadFactor);  
   accessOrder = false;    //链表中的元素默认按照插入顺序排序  
 }  

//覆写HashMap中的get方法,通过getEntry方法获取Entry对象。  
//注意这里的recordAccess方法,  
//如果链表中元素的排序规则是按照插入的先后顺序排序的话,该方法什么也不做,  
//如果链表中元素的排序规则是按照访问的先后顺序排序的话,则将e移到链表的末尾处。  
public V get(Object key) {  
     Entry<K,V> e = (Entry<K,V>)getEntry(key);  
     if (e == null)  
          return null;  
     e.recordAccess(this);  
     return e.value;  
}  
  
//覆写HashMap中的recordAccess方法(HashMap中该方法为空),  
//当调用父类的put方法,在发现插入的key已经存在时,会调用该方法,  
//调用LinkedHashmap覆写的get方法时,也会调用到该方法,  
//该方法提供了LRU算法的实现,它将最近使用的Entry放到双向循环链表的尾部,  
//accessOrder为true时,get方法会调用recordAccess方法  
//put方法在覆盖key-value对时也会调用recordAccess方法  
//它们导致Entry最近使用,因此将其移到双向链表的末尾  
void recordAccess(HashMap<K,V> m) {  
    LinkedHashMap<K,V> lm = (LinkedHashMap<K,V>)m;  
//如果链表中元素按照访问顺序排序,则将当前访问的Entry移到双向循环链表的尾部,  
//如果是按照插入的先后顺序排序,则不做任何事情。  
    if (lm.accessOrder) {  
        lm.modCount++;  
        //移除当前访问的Entry  
        remove();  
        //将当前访问的Entry插入到链表的尾部  
        addBefore(lm.header);  
       }  
}  

//双向循环立链表中,将当前的Entry插入到existingEntry的前面  
private void addBefore(Entry<K,V> existingEntry) {  
            after  = existingEntry;  
            before = existingEntry.before;  
            before.after = this;  
            after.before = this;  
        }  
  

可以看到accessOrder参数决定LinkedHashMap以什么方式排序,当里面的节点被访问后,如果accessOrder为true他就会被移到头节点上面。来保持以访问顺序排序

相关文章

  • LruCache

    LruCache的使用 LruCache部分源码解析 LruCache 利用 LinkedHashMap 的一个特...

  • Glide解析(一) - LruCache

    本文介绍的内容有 LruCache算法思想介绍 v4包中LruCache中源码解析 LruCache算法思想介绍 ...

  • Android基础(41)图片加载框架

    1)图片库对比2)Glide源码解析3)图片框架缓存实现4)LRUCache原理。LruCache默认缓存大小5)...

  • LruCache源码解析

    分析的LurCache来自于开源库picasso。一、LruCache初始化 LruCache初始化很简单,只用传...

  • LruCache源码解析

    LruCache 内部相当于维护了一个LinkedHashMap LinkedHashMap 结构为一个双向链表,...

  • LruCache源码解析

    在做缓存时,我们首先会做添加和获取缓存功能,而不管是内存缓存还是硬盘缓存,它们的缓存大小都是有限的。当缓存满了之后...

  • LruCache 源码解析

    简介 LRU 是 Least Recently Used 最近最少使用算法。 曾经,在各大缓存图片的框架没流行的时...

  • LruCache缓存类源码解析

    LruCache源码解析 LruCache是Android中的一个缓存工具类,它采用了一种最近最少使用算法,可以将...

  • Android LruCache 源码解析

    LruCache 是什么东西? LRU 咋一看这么熟悉,操作系统里面内存管理,页面置换时替换算法之一,英文全拼为L...

  • Android LruCache解析

    title: LruCache解析date: 2016-03-29tags: LruChche LruCache ...

网友评论

    本文标题:LruCache源码解析

    本文链接:https://www.haomeiwen.com/subject/myrnittx.html