关于LruCache

LinkedHashMap


  LruCache中维护了一个LinkedHashMap实例。缓存的实现主要由LinkedHashMap来完成。
  LinkedHashMap继承自HashMap,拥有HashMap的特性,比如线程不安全,初始容量是16,装载因子0.75等。
不同的是 其用双向循环链表把所有数据串在了一起。 LinkedHashMap中有两个重要的变量,分别是header和accessOrder,
如下:

/**
     * The head of the doubly linked list.
     */
    private transient LinkedHashMapEntry<K,V> header;


    /**
     * The iteration ordering method for this linked hash map: <tt>true</tt>
     * for access-order, <tt>false</tt> for insertion-order.
     *
     * @serial
     */
    private final boolean accessOrder;


   header代表链表的头部,accessOrder代表链表的排序方式(true:访问顺序,false:插入顺序)。其中当accessOrder为true时,每put或get一个元素,这个元素就会被放到链表尾部,也就是说,链表头部是最近最少使用的元素。根据这一点就可以来做缓存了。

/**
         * This method is invoked by the superclass whenever the value
         * of a pre-existing entry is read by Map.get or modified by Map.set.
         * If the enclosing Map is access-ordered, it moves the entry
         * to the end of the list; otherwise, it does nothing.
         */
        void recordAccess(HashMap<K,V> m) {
            LinkedHashMap<K,V> lm = (LinkedHashMap<K,V>)m;
            if (lm.accessOrder) {
                lm.modCount++;
                remove();
                addBefore(lm.header);
            }
        }


 上面的方法在get方法中调用,可以看到它对accessOrder进行了判断,addBefor中的内容如下

private void addBefore(LinkedHashMapEntry<K,V> existingEntry) {
            after  = existingEntry;
            before = existingEntry.before;
            before.after = this;
            after.before = this;
        }


 也就是将该元素移到链表末尾的操作。从而保证链表头部是最近最少使用的元素。


LruCache


 LruCache中维护了一个LinkedHashMap。需要注意的是,LindedHashMap不允许null键和null值。
在初始化LinkedHashMap时,构造方法有一个入参是maxSize。在每次执行put或者get操作时,
会把当前集合的大小和maxSize进行比较,若超过最大值,则移除最近最少使用的元素。

/**
     * Remove the eldest entries until the total of remaining entries is at or
     * below the requested size.
     *
     * @param maxSize the maximum size of the cache before returning. May be -1
     *            to evict even 0-sized elements.
     */
    public void trimToSize(int maxSize) {
        while (true) {
            K key;
            V value;
            synchronized (this) {
                if (size < 0 || (map.isEmpty() && size != 0)) {
                    throw new IllegalStateException(getClass().getName()
                            + ".sizeOf() is reporting inconsistent results!");
                }


                if (size <= maxSize) {
                    break;
                }


                Map.Entry<K, V> toEvict = map.eldest();
                if (toEvict == null) {
                    break;
                }


                key = toEvict.getKey();
                value = toEvict.getValue();
                map.remove(key);
                size -= safeSizeOf(key, value);
                evictionCount++;
            }


            entryRemoved(true, key, value, null);
        }
    }






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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值