Android LruCache类分析

[java]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. public class LurCache<K, V> {  
  2.     private final LinkedHashMap<K, V> map;  
  3.     private int size; // 已经存储的大小  
  4.     private int maxSize; // 规定的最大存储空间  
  5.     private int putCount; // put的次数  
  6.     private int createCount; // create的次数  
  7.     private int evictionCount; // 回收的次数  
  8.     private int hitCount; // 命中的次数  
  9.     private int missCount; // 丢失的次数  
  10.   
  11.     public LruCache(int maxSize) {  
  12.         if (maxSize <= 0) {  
  13.             throw new IllegalArgumentException("maxSize <= 0");  
  14.         }  
  15.         this.maxSize = maxSize;  
  16.         this.map = new LinkedHashMap<K, V>(00.75f, true);  
  17.     }  
  18.   
  19.     public final V get(K key) {  
  20.         if (key == null) {  
  21.             throw new NullPointerException("key == null");  
  22.         }  
  23.   
  24.         V mapValue;  
  25.         synchronized (this) {  
  26.             mapValue = map.get(key);  
  27.             if (mapValue != null) {  
  28.                 hitCount++; // 命中  
  29.                 return mapValue;  
  30.             }  
  31.             missCount++; // 丢失  
  32.         }  
  33.   
  34.         V createdValue = create(key);  
  35.         if (createdValue == null) {  
  36.             return null;  
  37.         }  
  38.   
  39.         synchronized (this) {  
  40.             createCount++;// 创建++  
  41.             mapValue = map.put(key, createdValue);  
  42.   
  43.             if (mapValue != null) {  
  44.                 // There was a conflict so undo that last put  
  45.                 // 如果前面存在oldValue,那么撤销put()  
  46.                 map.put(key, mapValue);  
  47.             } else {  
  48.                 size += safeSizeOf(key, createdValue);  
  49.             }  
  50.         }  
  51.         if (mapValue != null) {  
  52.             entryRemoved(false, key, createdValue, mapValue);  
  53.             return mapValue;  
  54.         } else {  
  55.             trimToSize(maxSize);  
  56.             return createdValue;  
  57.         }  
  58.     }  
  59.       
  60.     public final V put(K key, V value) {    
  61.         if (key == null || value == null) {    
  62.             throw new NullPointerException("key == null || value == null");    
  63.         }    
  64.     
  65.         V previous;    
  66.         synchronized (this) {    
  67.             putCount++;    
  68.             size += safeSizeOf(key, value);    
  69.             previous = map.put(key, value);    
  70.             if (previous != null) {  //返回的先前的value值  
  71.                 size -= safeSizeOf(key, previous);    
  72.             }    
  73.         }    
  74.     
  75.         if (previous != null) {    
  76.             entryRemoved(false, key, previous, value);    
  77.         }    
  78.     
  79.         trimToSize(maxSize);    
  80.         return previous;    
  81.     }    
  82.     //清空cache空间  
  83.     private void trimToSize(int maxSize) {    
  84.         while (true) {    
  85.             K key;    
  86.             V value;    
  87.             synchronized (this) {    
  88.                 if (size < 0 || (map.isEmpty() && size != 0)) {    
  89.                     throw new IllegalStateException(getClass().getName()    
  90.                             + ".sizeOf() is reporting inconsistent results!");    
  91.                 }    
  92.     
  93.                 if (size <= maxSize) {    
  94.                     break;    
  95.                 }    
  96.     
  97.                 Map.Entry<K, V> toEvict = map.entrySet().iterator().next();    
  98.                 if (toEvict == null) {    
  99.                     break;    
  100.                 }    
  101.     
  102.                 key = toEvict.getKey();    
  103.                 value = toEvict.getValue();    
  104.                 map.remove(key);    
  105.                 size -= safeSizeOf(key, value);    
  106.                 evictionCount++;    
  107.             }    
  108.     
  109.             entryRemoved(true, key, value, null);    
  110.         }    
  111.     }    
  112.     //删除key相应的cache项,返回相应的value  
  113.     public final V remove(K key) {    
  114.         if (key == null) {    
  115.             throw new NullPointerException("key == null");    
  116.         }    
  117.     
  118.         V previous;    
  119.         synchronized (this) {    
  120.             previous = map.remove(key);    
  121.             if (previous != null) {    
  122.                 size -= safeSizeOf(key, previous);    
  123.             }    
  124.         }    
  125.     
  126.         if (previous != null) {    
  127.             entryRemoved(false, key, previous, null);    
  128.         }    
  129.     
  130.         return previous;    
  131.     }    
  132.     //当item被回收或者删掉时调用。该方法当value被回收释放存储空间时被remove调用, 或者替换item值时put调用,默认实现什么都没做。  
  133.     //true: 为释放空间被删除;false: put或remove导致  
  134.     protected void entryRemoved(boolean evicted, K key, V oldValue, V newValue) {}   
  135.       
  136.     protected V create(K key) {    
  137.         return null;    
  138.     }    
  139.     
  140.     private int safeSizeOf(K key, V value) {    
  141.         int result = sizeOf(key, value);    
  142.         if (result < 0) {    
  143.             throw new IllegalStateException("Negative size: " + key + "=" + value);    
  144.         }    
  145.         return result;    
  146.     }    
  147.       
  148.     protected int sizeOf(K key, V value) {    
  149.         return 1;    
  150.     }  
  151.     //清空cache  
  152.     public final void evictAll() {    
  153.         trimToSize(-1); // -1 will evict 0-sized elements    
  154.     }  
  155.       
  156.     public synchronized final int size() {    
  157.         return size;    
  158.     }    
  159.     
  160.     public synchronized final int maxSize() {    
  161.         return maxSize;    
  162.     }    
  163.     
  164.     public synchronized final int hitCount() {    
  165.         return hitCount;    
  166.     }    
  167.     
  168.     public synchronized final int missCount() {    
  169.         return missCount;    
  170.     }    
  171.     
  172.     public synchronized final int createCount() {    
  173.         return createCount;    
  174.     }    
  175.     
  176.     public synchronized final int putCount() {    
  177.         return putCount;    
  178.     }    
  179.     
  180.     //返回被回收的数量  
  181.     public synchronized final int evictionCount() {    
  182.         return evictionCount;    
  183.     }    
  184.     //返回当前cache的副本,从最近最少访问到最多访问  
  185.     public synchronized final Map<K, V> snapshot() {    
  186.         return new LinkedHashMap<K, V>(map);    
  187.     }    
  188.     
  189.     public synchronized final String toString() {    
  190.         int accesses = hitCount + missCount;    
  191.         int hitPercent = accesses != 0 ? (100 * hitCount / accesses) : 0;    
  192.         return String.format("LruCache[maxSize=%d,hits=%d,misses=%d,hitRate=%d%%]",    
  193.                 maxSize, hitCount, missCount, hitPercent);    
  194.     }    
  195. }  
转自:http://blog.csdn.net/linghu_java/article/details/8574102
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值