`
hutuanle
  • 浏览: 9547 次
文章分类
社区版块
存档分类
最新评论

Android提供的LruCache类简介

 
阅读更多

摘自:http://blog.csdn.net/linghu_java/article/details/8574102

  • packageandroid.util;
  • importjava.util.LinkedHashMap;
  • importjava.util.Map;
  • /**
  • *Acachethatholdsstrongreferencestoalimitednumberofvalues.Eachtime
  • *avalueisaccessed,itismovedtotheheadofaqueue.Whenavalueis
  • *addedtoafullcache,thevalueattheendofthatqueueisevictedandmay
  • *becomeeligibleforgarbagecollection.
  • *Cache保存一个强引用来限制内容数量,每当Item被访问的时候,此Item就会移动到队列的头部。
  • * 当cache已满的时候加入新的item时,在队列尾部的item会被回收。
  • *<p>Ifyourcachedvaluesholdresourcesthatneedtobeexplicitlyreleased,
  • *override{@link#entryRemoved}.
  • *如果你cache的某个值需要明确释放,重写entryRemoved()
  • *<p>Ifacachemissshouldbecomputedondemandforthecorrespondingkeys,
  • *override{@link#create}.Thissimplifiesthecallingcode,allowingitto
  • *assumeavaluewillalwaysbereturned,evenwhenthere'sacachemiss.
  • *如果key相对应的item丢掉啦,重写create().这简化了调用代码,即使丢失了也总会返回。
  • *<p>Bydefault,thecachesizeismeasuredinthenumberofentries.Override
  • *{@link#sizeOf}tosizethecacheindifferentunits.Forexample,thiscache
  • *islimitedto4MiBofbitmaps:默认cache大小是测量的item的数量,重写sizeof计算不同item的
  • * 大小。
  • *<pre>{@code
  • *intcacheSize=4*1024*1024;//4MiB
  • *LruCache<String,Bitmap>bitmapCache=newLruCache<String,Bitmap>(cacheSize){
  • *protectedintsizeOf(Stringkey,Bitmapvalue){
  • *returnvalue.getByteCount();
  • *}
  • *}}</pre>
  • *
  • *<p>Thisclassisthread-safe.Performmultiplecacheoperationsatomicallyby
  • *synchronizingonthecache:<pre>{@code
  • *synchronized(cache){
  • *if(cache.get(key)==null){
  • *cache.put(key,value);
  • *}
  • *}}</pre>
  • *
  • *<p>Thisclassdoesnotallownulltobeusedasakeyorvalue.Areturn
  • *valueofnullfrom{@link#get},{@link#put}or{@link#remove}is
  • *unambiguous:thekeywasnotinthecache.
  • * 不允许key或者value为null
  • * 当get(),put(),remove()返回值为null时,key相应的项不在cache中
  • */
  • publicclassLruCache<K,V>{
  • privatefinalLinkedHashMap<K,V>map;
  • /**Sizeofthiscacheinunits.Notnecessarilythenumberofelements.*/
  • privateintsize; //已经存储的大小
  • privateintmaxSize; //规定的最大存储空间
  • privateintputCount; //put的次数
  • privateintcreateCount; //create的次数
  • privateintevictionCount; //回收的次数
  • privateinthitCount; //命中的次数
  • privateintmissCount; //丢失的次数
  • /**
  • *@parammaxSizeforcachesthatdonotoverride{@link#sizeOf},thisis
  • *themaximumnumberofentriesinthecache.Forallothercaches,
  • *thisisthemaximumsumofthesizesoftheentriesinthiscache.
  • */
  • publicLruCache(intmaxSize){
  • if(maxSize<=0){
  • thrownewIllegalArgumentException("maxSize<=0");
  • }
  • this.maxSize=maxSize;
  • this.map=newLinkedHashMap<K,V>(0,0.75f,true);
  • }
  • /**
  • *Returnsthevaluefor{@codekey}ifitexistsinthecacheorcanbe
  • *createdby{@code#create}.Ifavaluewasreturned,itismovedtothe
  • *headofthequeue.Thisreturnsnullifavalueisnotcachedandcannot
  • *becreated.通过key返回相应的item,或者创建返回相应的item。相应的item会移动到队列的头部,
  • * 如果item的value没有被cache或者不能被创建,则返回null。
  • */
  • publicfinalVget(Kkey){
  • if(key==null){
  • thrownewNullPointerException("key==null");
  • }
  • VmapValue;
  • synchronized(this){
  • mapValue=map.get(key);
  • if(mapValue!=null){
  • hitCount++; //命中
  • returnmapValue;
  • }
  • missCount++; //丢失
  • }
  • /*
  • *Attempttocreateavalue.Thismaytakealongtime,andthemap
  • *maybedifferentwhencreate()returns.Ifaconflictingvaluewas
  • *addedtothemapwhilecreate()wasworking,weleavethatvaluein
  • *themapandreleasethecreatedvalue.
  • * 如果丢失了就试图创建一个item
  • */
  • VcreatedValue=create(key);
  • if(createdValue==null){
  • returnnull;
  • }
  • synchronized(this){
  • createCount++;//创建++
  • mapValue=map.put(key,createdValue);
  • if(mapValue!=null){
  • //Therewasaconflictsoundothatlastput
  • //如果前面存在oldValue,那么撤销put()
  • map.put(key,mapValue);
  • }else{
  • size+=safeSizeOf(key,createdValue);
  • }
  • }
  • if(mapValue!=null){
  • entryRemoved(false,key,createdValue,mapValue);
  • returnmapValue;
  • }else{
  • trimToSize(maxSize);
  • returncreatedValue;
  • }
  • }
  • /**
  • *Caches{@codevalue}for{@codekey}.Thevalueismovedtotheheadof
  • *thequeue.
  • *
  • *@returnthepreviousvaluemappedby{@codekey}.
  • */
  • publicfinalVput(Kkey,Vvalue){
  • if(key==null||value==null){
  • thrownewNullPointerException("key==null||value==null");
  • }
  • Vprevious;
  • 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);
  • returnprevious;
  • }
  • /**
  • *@parammaxSizethemaximumsizeofthecachebeforereturning.Maybe-1
  • *toevicteven0-sizedelements.
  • * 清空cache空间
  • */
  • privatevoidtrimToSize(intmaxSize){
  • while(true){
  • Kkey;
  • Vvalue;
  • synchronized(this){
  • if(size<0||(map.isEmpty()&&size!=0)){
  • thrownewIllegalStateException(getClass().getName()
  • +".sizeOf()isreportinginconsistentresults!");
  • }
  • if(size<=maxSize){
  • break;
  • }
  • Map.Entry<K,V>toEvict=map.eldest();
  • if(toEvict==null){
  • break;
  • }
  • key=toEvict.getKey();
  • value=toEvict.getValue();
  • map.remove(key);
  • size-=safeSizeOf(key,value);
  • evictionCount++;
  • }
  • entryRemoved(true,key,value,null);
  • }
  • }
  • /**
  • *Removestheentryfor{@codekey}ifitexists.
  • *删除key相应的cache项,返回相应的value
  • *@returnthepreviousvaluemappedby{@codekey}.
  • */
  • publicfinalVremove(Kkey){
  • if(key==null){
  • thrownewNullPointerException("key==null");
  • }
  • Vprevious;
  • synchronized(this){
  • previous=map.remove(key);
  • if(previous!=null){
  • size-=safeSizeOf(key,previous);
  • }
  • }
  • if(previous!=null){
  • entryRemoved(false,key,previous,null);
  • }
  • returnprevious;
  • }
  • /**
  • *Calledforentriesthathavebeenevictedorremoved.Thismethodis
  • *invokedwhenavalueisevictedtomakespace,removedbyacallto
  • *{@link#remove},orreplacedbyacallto{@link#put}.Thedefault
  • *implementationdoesnothing.
  • *当item被回收或者删掉时调用。改方法当value被回收释放存储空间时被remove调用,
  • * 或者替换item值时put调用,默认实现什么都没做。
  • *<p>Themethodiscalledwithoutsynchronization:otherthreadsmay
  • *accessthecachewhilethismethodisexecuting.
  • *
  • *@paramevictedtrueiftheentryisbeingremovedtomakespace,false
  • *iftheremovalwascausedbya{@link#put}or{@link#remove}.
  • * true---为释放空间被删除;false---put或remove导致
  • *@paramnewValuethenewvaluefor{@codekey},ifitexists.Ifnon-null,
  • *thisremovalwascausedbya{@link#put}.Otherwiseitwascausedby
  • *anevictionora{@link#remove}.
  • */
  • protectedvoidentryRemoved(booleanevicted,Kkey,VoldValue,VnewValue){}
  • /**
  • *Calledafteracachemisstocomputeavalueforthecorrespondingkey.
  • *Returnsthecomputedvalueornullifnovaluecanbecomputed.The
  • *defaultimplementationreturnsnull.
  • *当某Item丢失时会调用到,返回计算的相应的value或者null
  • *<p>Themethodiscalledwithoutsynchronization:otherthreadsmay
  • *accessthecachewhilethismethodisexecuting.
  • *
  • *<p>Ifavaluefor{@codekey}existsinthecachewhenthismethod
  • *returns,thecreatedvaluewillbereleasedwith{@link#entryRemoved}
  • *anddiscarded.Thiscanoccurwhenmultiplethreadsrequestthesamekey
  • *atthesametime(causingmultiplevaluestobecreated),orwhenone
  • *threadcalls{@link#put}whileanotheriscreatingavalueforthesame
  • *key.
  • */
  • protectedVcreate(Kkey){
  • returnnull;
  • }
  • privateintsafeSizeOf(Kkey,Vvalue){
  • intresult=sizeOf(key,value);
  • if(result<0){
  • thrownewIllegalStateException("Negativesize:"+key+"="+value);
  • }
  • returnresult;
  • }
  • /**
  • *Returnsthesizeoftheentryfor{@codekey}and{@codevalue}in
  • *user-definedunits.Thedefaultimplementationreturns1sothatsize
  • *isthenumberofentriesandmaxsizeisthemaximumnumberofentries.
  • *返回用户定义的item的大小,默认返回1代表item的数量,最大size就是最大item值
  • *<p>Anentry'ssizemustnotchangewhileitisinthecache.
  • */
  • protectedintsizeOf(Kkey,Vvalue){
  • return1;
  • }
  • /**
  • *Clearthecache,calling{@link#entryRemoved}oneachremovedentry.
  • * 清空cacke
  • */
  • publicfinalvoidevictAll(){
  • trimToSize(-1);//-1willevict0-sizedelements
  • }
  • /**
  • *Forcachesthatdonotoverride{@link#sizeOf},thisreturnsthenumber
  • *ofentriesinthecache.Forallothercaches,thisreturnsthesumof
  • *thesizesoftheentriesinthiscache.
  • */
  • publicsynchronizedfinalintsize(){
  • returnsize;
  • }
  • /**
  • *Forcachesthatdonotoverride{@link#sizeOf},thisreturnsthemaximum
  • *numberofentriesinthecache.Forallothercaches,thisreturnsthe
  • *maximumsumofthesizesoftheentriesinthiscache.
  • */
  • publicsynchronizedfinalintmaxSize(){
  • returnmaxSize;
  • }
  • /**
  • *Returnsthenumberoftimes{@link#get}returnedavaluethatwas
  • *alreadypresentinthecache.
  • */
  • publicsynchronizedfinalinthitCount(){
  • returnhitCount;
  • }
  • /**
  • *Returnsthenumberoftimes{@link#get}returnednullorrequiredanew
  • *valuetobecreated.
  • */
  • publicsynchronizedfinalintmissCount(){
  • returnmissCount;
  • }
  • /**
  • *Returnsthenumberoftimes{@link#create(Object)}returnedavalue.
  • */
  • publicsynchronizedfinalintcreateCount(){
  • returncreateCount;
  • }
  • /**
  • *Returnsthenumberoftimes{@link#put}wascalled.
  • */
  • publicsynchronizedfinalintputCount(){
  • returnputCount;
  • }
  • /**
  • *Returnsthenumberofvaluesthathavebeenevicted.
  • * 返回被回收的数量
  • */
  • publicsynchronizedfinalintevictionCount(){
  • returnevictionCount;
  • }
  • /**
  • *Returnsacopyofthecurrentcontentsofthecache,orderedfromleast
  • *recentlyaccessedtomostrecentlyaccessed.返回当前cache的副本,从最近最少访问到最多访问
  • */
  • publicsynchronizedfinalMap<K,V>snapshot(){
  • returnnewLinkedHashMap<K,V>(map);
  • }
  • @OverridepublicsynchronizedfinalStringtoString(){
  • intaccesses=hitCount+missCount;
  • inthitPercent=accesses!=0?(100*hitCount/accesses):0;
  • returnString.format("LruCache[maxSize=%d,hits=%d,misses=%d,hitRate=%d%%]",
  • maxSize,hitCount,missCount,hitPercent);
  • }
  • }
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics