- package android.util;
- import java.util.LinkedHashMap;
- import java.util.Map;
- /**
- * A cache that holds strong references to a limited number of values. Each time
- * a value is accessed, it is moved to the head of a queue. When a value is
- * added to a full cache, the value at the end of that queue is evicted and may
- * become eligible for garbage collection.
- * Cache保存一个强引用来限制内容数量,每当Item被访问的时候,此Item就会移动到队列的头部。
- * 当cache已满的时候加入新的item时,在队列尾部的item会被回收。
- * <p>If your cached values hold resources that need to be explicitly released,
- * override {@link #entryRemoved}.
- * 如果你cache的某个值需要明确释放,重写entryRemoved()
- * <p>If a cache miss should be computed on demand for the corresponding keys,
- * override {@link #create}. This simplifies the calling code, allowing it to
- * assume a value will always be returned, even when there's a cache miss.
- * 如果key相对应的item丢掉啦,重写create().这简化了调用代码,即使丢失了也总会返回。
- * <p>By default, the cache size is measured in the number of entries. Override
- * {@link #sizeOf} to size the cache in different units. For example, this cache
- * is limited to 4MiB of bitmaps: 默认cache大小是测量的item的数量,重写sizeof计算不同item的
- * 大小。
- * <pre> {@code
- * int cacheSize = 4 * 1024 * 1024; // 4MiB
- * LruCache<String, Bitmap> bitmapCache = new LruCache<String, Bitmap>(cacheSize) {
- * protected int sizeOf(String key, Bitmap value) {
- * return value.getByteCount();
- * }
- * }}</pre>
- *
- * <p>This class is thread-safe. Perform multiple cache operations atomically by
- * synchronizing on the cache: <pre> {@code
- * synchronized (cache) {
- * if (cache.get(key) == null) {
- * cache.put(key, value);
- * }
- * }}</pre>
- *
- * <p>This class does not allow null to be used as a key or value. A return
- * value of null from {@link #get}, {@link #put} or {@link #remove} is
- * unambiguous: the key was not in the cache.
- * 不允许key或者value为null
- * 当get(),put(),remove()返回值为null时,key相应的项不在cache中
- */
- public class LruCache<K, V> {
- private final LinkedHashMap<K, V> map;
- /** Size of this cache in units. Not necessarily the number of elements. */
-
private int size;
//已经存储的大小 -
private int maxSize;
//规定的最大存储空间 -
private int putCount;
//put的次数 -
private int createCount;
//create的次数 -
private int evictionCount;
//回收的次数 -
private int hitCount;
//命中的次数 -
private int missCount;
//丢失的次数 - /**
- * @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);
- }
- /**
- * Returns the value for {@code key} if it exists in the cache or can be
- * created by {@code #create}. If a value was returned, it is moved to the
- * head of the queue. This returns null if a value is not cached and cannot
- * be created. 通过key返回相应的item,或者创建返回相应的item。相应的item会移动到队列的头部,
- * 如果item的value没有被cache或者不能被创建,则返回null。
- */
- 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++; //丢失
- }
- /*
- * Attempt to create a value. This may take a long time, and the map
- * may be different when create() returns. If a conflicting value was
- * added to the map while create() was working, we leave that value in
- * the map and release the created value.
- * 如果丢失了就试图创建一个item
- */
- V createdValue = create(key);
- if (createdValue == null) {
- return null;
- }
- synchronized (this) {
- createCount++;//创建++
- mapValue = map.put(key, createdValue);