Public classLurcache<k, v> { PrivateFinal Linkedhashmap<k, v>map; Private intSize//size that has been stored Private intMaxSize;//Maximum storage space specified Private intPutcount;//number of Put Private intCreatecount;//Number of Create Private intEvictioncount;//Number of recoveries Private intHitCount;//Number of hits Private intMisscount;//Number of Lost PublicLruCache (intmaxSize) { if(MaxSize <=0) { Throw NewIllegalArgumentException ("maxSize <= 0"); } This. maxSize =maxSize; This. Map =NewLinkedhashmap<k, V> (0,0.75f,true); } PublicFinal VGet(K key) {if(Key = =NULL) { Throw NewNullPointerException ("key = = NULL"); } V Mapvalue; Synchronized ( This) {Mapvalue= map.Get(key); if(Mapvalue! =NULL) {HitCount++;//hit returnMapvalue; } Misscount++;//lost} V Createdvalue=Create (key); if(Createdvalue = =NULL) { return NULL; } synchronized ( This) {Createcount++;//Create + +Mapvalue =map.put (key, Createdvalue); if(Mapvalue! =NULL) { //There is a conflict so undo the last put//if OldValue is present, then undo put ()map.put (key, Mapvalue); } Else{size+=safesizeof (key, Createdvalue); } } if(Mapvalue! =NULL) {entryremoved (false, Key, Createdvalue, Mapvalue); returnMapvalue; } Else{trimtosize (maxSize); returnCreatedvalue; } } Publicfinal V put (K key, V value) {if(Key = =NULL|| Value = =NULL) { Throw NewNullPointerException ("key = = NULL | | value = = NULL"); } V Previous; Synchronized ( This) {Putcount++; Size+=safesizeof (key, value); Previous=map.put (key, value); if(Previous! =NULL) {//the value of the previous value returnedSize-=safesizeof (key, previous); } } if(Previous! =NULL) {entryremoved (false, key, Previous, value); } trimtosize (MaxSize); returnprevious; } //empty the cache space Private voidTrimToSize (intmaxSize) { while(true) {K key; V value; Synchronized ( This) { if(Size <0|| (Map.isempty () && Size! =0)) { Throw Newillegalstateexception (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); } } //Delete the corresponding cache entry for key and return the corresponding value Publicfinal V Remove (K key) {if(Key = =NULL) { Throw NewNullPointerException ("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); } returnprevious; } //called when item is recycled or erased. This method is called by remove when value is reclaimed to free storage space, or when a put call is replaced with the item value, and the default implementation does nothing. //true: To free space is removed; False:put or remove causes protected voidentryremoved (Boolean evicted, K key, v OldValue, v newvalue) {}protectedV Create (K key) {return NULL; } Private intsafesizeof (K key, V value) {intresult =sizeOf (key, value); if(Result <0) { Throw NewIllegalStateException ("Negative Size:"+ key +"="+value); } returnresult; } protected intsizeOf (K key, V value) {return 1; } //Empty Cache PublicFinalvoidEvictall () {trimtosize (-1);//-1 'll evict 0-sized elements } PublicSynchronized finalintsize () {returnsize; } PublicSynchronized finalintmaxSize () {returnmaxSize; } PublicSynchronized finalintHitCount () {returnHitCount; } PublicSynchronized finalintMisscount () {returnMisscount; } PublicSynchronized finalintCreatecount () {returnCreatecount; } PublicSynchronized finalintPutcount () {returnPutcount; } //returns the number of recycled PublicSynchronized finalintEvictioncount () {returnEvictioncount; } //returns a copy of the current cache, from the least recently accessed to the most visited PublicSynchronized final map<k, v>Snapshot () {return NewLinkedhashmap<k, v>(map); } PublicSynchronized Final String toString () {intAccesses = HitCount +Misscount; intHitpercent = accesses! =0? ( -* hitcount/accesses):0; returnString.Format ("lrucache[maxsize=%d,hits=%d,misses=%d,hitrate=%d%%]", MaxSize, HitCount, Misscount, hitpercent); } }
Android LRUCache Class Analysis