Android LruCache类分析

public class LurCache<K, V> {
	private final LinkedHashMap<K, V> map;
	private int size; // 已经存储的大小
	private int maxSize; // 规定的最大存储空间
	private int putCount; // put的次数
	private int createCount; // create的次数
	private int evictionCount; // 回收的次数
	private int hitCount; // 命中的次数
	private int missCount; // 丢失的次数

	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);
	}

	public final V get(K key) {
		if (key == null) {
			throw new NullPointerException("key == null");
		}

		V mapValue;
		synchronized (this) {
			mapValue = map.get(key);
			if (mapValue != null) {
				hitCount++; // 命中
				return mapValue;
			}
			missCount++; // 丢失
		}

		V createdValue = create(key);
		if (createdValue == null) {
			return null;
		}

		synchronized (this) {
			createCount++;// 创建++
			mapValue = map.put(key, createdValue);

			if (mapValue != null) {
				// There was a conflict so undo that last put
				// 如果前面存在oldValue,那么撤销put()
				map.put(key, mapValue);
			} else {
				size += safeSizeOf(key, createdValue);
			}
		}
		if (mapValue != null) {
			entryRemoved(false, key, createdValue, mapValue);
			return mapValue;
		} else {
			trimToSize(maxSize);
			return createdValue;
		}
	}
	
	public final V put(K key, V value) {  
        if (key == null || value == null) {  
            throw new NullPointerException("key == null || value == null");  
        }  
  
        V previous;  
        synchronized (this) {  
            putCount++;  
            size += safeSizeOf(key, value);  
            previous = map.put(key, value);  
            if (previous != null) {  //返回的先前的value值
                size -= safeSizeOf(key, previous);  
            }  
        }  
  
        if (previous != null) {  
            entryRemoved(false, key, previous, value);  
        }  
  
        trimToSize(maxSize);  
        return previous;  
    }  
	//清空cache空间
	private 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.entrySet().iterator().next();  
                if (toEvict == null) {  
                    break;  
                }  
  
                key = toEvict.getKey();  
                value = toEvict.getValue();  
                map.remove(key);  
                size -= safeSizeOf(key, value);  
                evictionCount++;  
            }  
  
            entryRemoved(true, key, value, null);  
        }  
    }  
	//删除key相应的cache项,返回相应的value
	public final V remove(K key) {  
        if (key == null) {  
            throw new NullPointerException("key == null");  
        }  
  
        V previous;  
        synchronized (this) {  
            previous = map.remove(key);  
            if (previous != null) {  
                size -= safeSizeOf(key, previous);  
            }  
        }  
  
        if (previous != null) {  
            entryRemoved(false, key, previous, null);  
        }  
  
        return previous;  
    }  
	//当item被回收或者删掉时调用。该方法当value被回收释放存储空间时被remove调用, 或者替换item值时put调用,默认实现什么都没做。
	//true: 为释放空间被删除;false: put或remove导致
	protected void entryRemoved(boolean evicted, K key, V oldValue, V newValue) {} 
	
	protected V create(K key) {  
        return null;  
    }  
  
    private int safeSizeOf(K key, V value) {  
        int result = sizeOf(key, value);  
        if (result < 0) {  
            throw new IllegalStateException("Negative size: " + key + "=" + value);  
        }  
        return result;  
    }  
    
    protected int sizeOf(K key, V value) {  
        return 1;  
    }
    //清空cache
    public final void evictAll() {  
        trimToSize(-1); // -1 will evict 0-sized elements  
    }
    
    public synchronized final int size() {  
        return size;  
    }  
  
    public synchronized final int maxSize() {  
        return maxSize;  
    }  
  
    public synchronized final int hitCount() {  
        return hitCount;  
    }  
  
    public synchronized final int missCount() {  
        return missCount;  
    }  
  
    public synchronized final int createCount() {  
        return createCount;  
    }  
  
    public synchronized final int putCount() {  
        return putCount;  
    }  
  
    //返回被回收的数量
    public synchronized final int evictionCount() {  
        return evictionCount;  
    }  
    //返回当前cache的副本,从最近最少访问到最多访问
    public synchronized final Map<K, V> snapshot() {  
        return new LinkedHashMap<K, V>(map);  
    }  
  
    public synchronized final String toString() {  
        int accesses = hitCount + missCount;  
        int hitPercent = accesses != 0 ? (100 * hitCount / accesses) : 0;  
        return String.format("LruCache[maxSize=%d,hits=%d,misses=%d,hitRate=%d%%]",  
                maxSize, hitCount, missCount, hitPercent);  
    }  
}
转自:http://blog.csdn.net/linghu_java/article/details/8574102
  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值