LinkedHashMap---LruCache

总结:

1.LinkedHashMap是继承于HashMap,是基于数组 和 双向链表来实现的。

2.HashMap无序;LinkedHashMap有序,可分为插入顺序 和 访问顺序两种。如果是访问顺序,那put 和 get操作已存在的Entry时,都会把Entry移动到双向链表的表尾(其实是先删除 再插入)

3.LinkedHashMap存取数据,还是跟HashMap一样使用的Entry[]的方式,双向链表只是为了保证顺序。

4.LinkedHashMap是线程不安全的,HashMap也是线程不安全的。

 

LinkedHashMap存储数据是有序的,分为两种:插入顺序 和 访问顺序。

空参构造

public LinkedHashMap() {

      // 调用HashMap的构造方法,其实就是初始化Entry[] table
      super();
      // 这里是指是否基于访问排序,默认为false
      accessOrder = false;
}

带参构造

public LinkedHashMap(int initialCapacity,
                         float loadFactor,
                         boolean accessOrder) {

       super(initialCapacity, loadFactor);
       this.accessOrder = accessOrder;
}

其中accessOrder设置为false,则为插入顺序,否则为访问顺序。

举个例子:

accessOrder为true

public static void main(String[] args){
    LinkedHashMap<Integer, Integer> map = new LinkedHashMap<>(0, 0.75f, true);
    map.put(0, 0);
    map.put(1, 1);
    map.put(2, 2);
    map.put(3, 3);
    map.put(4, 4);

    map.get(1);
    map.get(2);

    for(Map.Entry<Integer, Integer> entry: map.entrySet()){
        System.out.println(entry.getKey() + ":" + entry.getValue());
    }
}

最终输出结果是

0:0
3:3
4:4
1:1
2:2

也就是说最近访问的被放到了头部,最后输出,这正好满足LRU缓存算法的思想。LruCache的实现,正是利用了LinkedHashMap的这种数据结构。

 

android中的缓存策略

一般来说,缓存策略主要包含缓存的添加、获取 和 删除这三类操作。添加和获取缓存比较好理解,那么为什么还要删除缓存呢?这是因为不管是内存缓存 还是硬盘缓存,它们的缓存大小都是有限的。当缓存满了以后,再想添加缓存,就需要删除一些旧的缓存 并添加新的缓存。

因此,LRU(Least Recently Used)缓存算法应运而生,LRU是近期最少使用的算法,它的核心思想是当缓存满时,会优先删除那些近期最少使用的缓存对象。采用LRU算法的缓存有两种:LruCache 和 DiskLruCache,分别用于实现内存缓存 和 硬盘缓存,其核心思想都是LRU缓存算法。

LruCache的使用

使用很简单,以缓存图片为例,只需两步

1)设置LruCache缓存的大小,一般为当前进程可用容量的1/8.

2)重写sizeOf方法,计算出要缓存的每张图片的大小,默认返回图片的数量。

int maxMemory = (int)(Runtime.getRuntime().maxMemory() / 1024);
int cacheSize = maxMemory/8;
LruCache mMemoryCache = new LruCache<String, Bitmap>(cacheSize){
    @Override
    protected int sizeOf(String key, Bitmap value){
        return value.getRowBytes() * value.getHeight() / 1024;
    }
};

LruCache的实现原理

核心思想就是要维护一个缓存对象列表,其中对象列表的排列方式是按照访问顺序实现的,即一直没被访问的对象,将放在队尾,即将被淘汰;而最近访问的对象将放在对头,最后被淘汰。

那么这个缓存队列由谁维护呢,答案是:LinkedHashMap。

因为双向链表结构 可以实现访问顺序 和 插入顺序,使得LinkedHashMap中的键值对按照一定的顺序排列起来。

总结就是:

LruCache中维护了一个LinkedHashMap集合,该LinkedHashMap是以访问顺序排序的。当调用put方法时,就会在集合中添加元素,并调用trimToSize()判断缓存是否已满。如果满了就用LinkedHashMap的迭代器删除队尾元素,即最近最少访问的元素。当调用get()方法访问缓存对象时,就会调用LinkedHashMap的get()方法获得对应集合元素,同时会更新该元素到队头。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值