首页 > 代码库 > Android LruCache类分析

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 =http://www.mamicode.com/= null) {            return null;        }        synchronized (this) {            createCount++;// 创建++            mapValue =http://www.mamicode.com/ 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 =http://www.mamicode.com/= null) {              throw new NullPointerException("key == null || value =http://www.mamicode.com/= 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);      }  }

 

Android LruCache类分析