principle:
LRUCache is initialized in the form of a key-value pair, the size of the cache must be set to K, and data beyond this size will be erased. Note: The data that is purged is the data that was added first. The data structure inside the LRUCache is Linkedhashmap stored. In this way, the LRUCache reaches the K data that caches the most recent put.
Use:
[Code]
int cacheSize = 4 * 1024 * 1024; 4MiB LruCache bitmapcache = new LruCache (cacheSize) { protected int sizeOf (String key, Bitmap value) { Retu RN Value.getbytecount (); }}
Note that caching of different data requires rewriting the sizeof method. For example, the above cache is a picture. In essence, this data is stored in memory, so cachesize is not easy to be too large.
LRUCache Source code:
Import Java.util.linkedhashmap;import Java.util.Map; public class Lrucache<k, v> {private final linkedhashmap<k, v> map; private int size; private int maxSize; private int putcount; private int createcount; 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) {returnNull } synchronized (this) {createcount++; Mapvalue = Map.put (key, Createdvalue); if (mapvalue! = null) {//There is a conflict so undo the last 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 Nullpointe Rexception ("key = = NULL | | Value = = null "); } V Previous; Synchronized (this) {putcount++; Size + = safesizeof (key, value); Previous = Map.put (key, value); if (previous! = NULL) {Size-= safesizeof (key, previous); } } if (previous! = null) {entryremoved (False, key, previous, value); } trimtosize (MaxSize); return previous; } 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 Repor Ting inconsistent results! ");} if (size <= maxSize | | map.isempty ()) {break; } map.entry<k, v> toevict = Map.entryset (). iterator (). Next (); Key = Toevict.getkey (); Value = Toevict.getvalue (); Map.Remove (key); Size-= safesizeof (key, value); evictioncount++; } entryremoved (True, key, value, NULL); }} 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; } 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; }/** * Clear the cache, calling {@link #entryRemoved} on each removed entry. */public final void Evictall () { TrimToSize (-1); -1 'll 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; }/** * Returns the number of times {@link #put} was called. */public synchronized final int Putcount () {return putcount; }/** * Returns the number of values that has been evicted. */public synchronized final int Evictioncount () {return evictioncount; }/** * Returns a copy of the current contents of the cache, ordered from least * recently accessed to most RE cently accessed. */Public synchronized final map<k, v> snapshot () {return new linkedhashmap<k, v> (MAP); } @Override public Synchronized Final String toString () {int accesses = HitCount + Misscount; int hitpercent = accesses! = 0? (hitcount/accesses): 0; Return String.Format ("lrucache[maxsize=%d,hits=%d,misses=%d,hitrate=%d%%"), MaxSize, HitCount, Misscount, H Itpercent); }}
From the source code, we can clearly see the LRUCache caching mechanism.
-------------------------------------------------------------------
more communication, Android Development Alliance QQ Group: 272209595
Android:lrucache Cache Summary