为ThreadLocal定制的ThreadLocalMap

ThreadLocalMapjava.lang.ThreadLocal的静态内部类ThreadLocalMap表面看起来至少实现类似hashmap的功能,但是仔细分析它却有下面的属性。
<wbr style="line-height:25px">首先<wbr style="line-height:25px">,</wbr></wbr>它只是尽量的让value保持在哈希值的位置或后面,
<wbr style="line-height:25px"><span style="color:#993300; line-height:25px">其次<wbr style="line-height:25px">,</wbr></span>它提供了对不同key(这里是ThreadLocal)对象的但hashCode相同的存储的支持。<br style="line-height:25px"><wbr style="line-height:25px"><span style="color:#993300; line-height:25px">最后<wbr style="line-height:25px">,</wbr></span>它对Key的引用是弱引用。这个和<span style="color:#ff6600; line-height:25px">WeakHashMap</span>一致。但这个和hashMap有点不一样,hashMap要使用用弱引用的话,<br style="line-height:25px"> 一般是对value进行弱引用的,而不是key.<br style="line-height:25px"> 也许有一天我们在自己的程序中需要类似ThreadLocalMap的功能。<br style="line-height:25px"> 以下是从<wbr style="line-height:25px"><span style="color:#ff00ff; line-height:25px">ThreadLocalMap</span><span style="color:#000080; line-height:25px">简化而来</span><wbr style="line-height:25px">的代码:<br style="line-height:25px"> 其中Key对应JDK中的ThreadLocal<br style="line-height:25px"><span style="color:#993300; line-height:25px">class</span><span style="color:#3366ff; line-height:25px"></span><span style="color:#ff6600; line-height:25px">Key</span><span style="color:#3366ff; line-height:25px">{</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">finalinthashCode=nextHashCode();</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px"></span><span style="color:#993300; line-height:25px">static</span><span style="color:#3366ff; line-height:25px">AtomicIntegernextHashCode=</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">newAtomicInteger();</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">staticfinalintHASH_INCREMENT=0x61c88647;</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px"></span><span style="color:#993300; line-height:25px">staticint</span><span style="color:#3366ff; line-height:25px">nextHashCode(){</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">returnnextHashCode.getAndAdd(HASH_INCREMENT);</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">}</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">}</span><br style="line-height:25px"><span style="color:#993300; line-height:25px">class</span><span style="color:#3366ff; line-height:25px">ThreadLocalMap{</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px"></span><span style="color:#993300; line-height:25px">staticclass</span><span style="color:#3366ff; line-height:25px">Entry</span><span style="color:#993300; line-height:25px">extends</span><span style="color:#3366ff; line-height:25px">WeakReference&lt;Key&gt;{</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">Objectvalue;</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">Entry(Keyk,Objectv){</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px"></span><span style="color:#993300; line-height:25px">super</span><span style="color:#3366ff; line-height:25px">(k);</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">value=v;</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">}</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">}</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px"> </span><span style="color:#808080; line-height:25px">//初始值,必须是2的n次方</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px"></span><span style="color:#0000ff; line-height:25px">privatestaticfinalintINITIAL_CAPACITY=16;</span><br style="line-height:25px"><span style="color:#808080; line-height:25px">/**<br style="line-height:25px"> *Thetable,resizedasnecessary.<br style="line-height:25px"> *table.lengthMUSTalwaysbeapoweroftwo.<br style="line-height:25px"> */</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">privateEntry[]table;</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">privateintsize=0;</span><br style="line-height:25px"><span style="color:#808080; line-height:25px">/**<br style="line-height:25px"> *Thenextsizevalueatwhichtoresize.<br style="line-height:25px"> */</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">privateintthreshold;//Defaultto0</span><br style="line-height:25px"><span style="color:#808080; line-height:25px">/**<br style="line-height:25px"> *Settheresizethresholdtomaintainatworsta2/3loadfactor.<br style="line-height:25px"> */</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">privatevoidsetThreshold(intlen){</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">threshold=len*2/3;</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">}</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">privatestaticintnextIndex(inti,intlen){</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">return((i+1&lt;len)?i+1:0);</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">}</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">privatestaticintprevIndex(inti,intlen){</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">return((i-1&gt;=0)?i-1:len-1);</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">}</span><br style="line-height:25px"><span style="color:#808080; line-height:25px">/**<br style="line-height:25px"> *Constructanewmapinitiallycontaining(firstKey,firstValue).<br style="line-height:25px"> *ThreadLocalMapsareconstructedlazily,soweonlycreate<br style="line-height:25px"> *onewhenwehaveatleastoneentrytoputinit.<br style="line-height:25px"> */</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">ThreadLocalMap(KeyfirstKey,ObjectfirstValue){</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">table=newEntry[INITIAL_CAPACITY];</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">inti=firstKey.hashCode&amp;(INITIAL_CAPACITY-1);</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">table</span><wbr style="line-height:25px"><span style="color:#3366ff; line-height:25px">=newEntry(firstKey,firstValue);</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">size=1;</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">setThreshold(INITIAL_CAPACITY);</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">}</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px"></span><span style="color:#993300; line-height:25px">private</span><span style="color:#3366ff; line-height:25px">EntrygetEntry(Keykey){</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">inti=key.hashCode&amp;(table.length-1);</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">Entrye=table[i]</span><wbr style="line-height:25px"><span style="color:#3366ff; line-height:25px">;</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px"></span><span style="color:#993300; line-height:25px">if</span><span style="color:#3366ff; line-height:25px">(e!=null&amp;&amp;e.get()==key)</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px"></span><span style="color:#993300; line-height:25px">return</span><span style="color:#3366ff; line-height:25px">e;</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px"></span><span style="color:#993300; line-height:25px">else</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px"></span><span style="color:#993300; line-height:25px">return</span><span style="color:#3366ff; line-height:25px">getEntryAfterMiss(key,i,e);</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">}</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px"></span><span style="color:#993300; line-height:25px">private</span><span style="color:#3366ff; line-height:25px">EntrygetEntryAfterMiss(Keykey,inti,Entrye){</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">Entry[]tab=table[i];</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">intlen=tab.length;</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px"></span><span style="color:#993300; line-height:25px">while</span><span style="color:#3366ff; line-height:25px">(e!=null){</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">Keyk=e.get();</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px"></span><span style="color:#993300; line-height:25px">if</span><span style="color:#3366ff; line-height:25px">(k==key)</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">returne;</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px"></span><span style="color:#993300; line-height:25px">if</span><span style="color:#3366ff; line-height:25px">(k==null)</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">expungeStaleEntry(i);</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px"></span><span style="color:#993300; line-height:25px">else</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">i=nextIndex(i,len);</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">e=tab[i]</span><wbr style="line-height:25px"><span style="color:#3366ff; line-height:25px">;</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">}</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">returnnull;</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">}</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px"></span><span style="color:#993300; line-height:25px">privatevoid</span><span style="color:#3366ff; line-height:25px">set(Keykey,Objectvalue){</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">Entry[]tab=table;</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">intlen=tab.length;</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">inti=key.hashCode&amp;(len-1);</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px"></span><span style="color:#993300; line-height:25px">for</span><span style="color:#3366ff; line-height:25px">(Entrye=tab[i]</span><wbr style="line-height:25px"><span style="color:#3366ff; line-height:25px">;</span><span style="color:#3366ff; line-height:25px">e!=null;</span><span style="color:#3366ff; line-height:25px">e=tab[i=nextIndex(i,len)]){</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">Keyk=e.get();</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px"></span><span style="color:#993300; line-height:25px">if</span><span style="color:#3366ff; line-height:25px">(k==key){</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">e.value=value;</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">return;</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">}</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px"></span><span style="color:#993300; line-height:25px">if</span><span style="color:#3366ff; line-height:25px">(k==null){</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">replaceStaleEntry(key,value,i);</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">return;</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">}</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">}</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">tab</span><wbr style="line-height:25px"><span style="color:#3366ff; line-height:25px">=newEntry(key,value);</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">intsz=++size;</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">if(!cleanSomeSlots(i,sz)&amp;&amp;sz&gt;=threshold)</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">rehash();</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">}</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">privatevoidremove(Keykey){</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">Entry[]tab=table;</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">intlen=tab.length;</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">inti=key.hashCode&amp;(len-1);</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">for(Entrye=tab</span><wbr style="line-height:25px"><span style="color:#3366ff; line-height:25px">;</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">e!=null;</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">e=tab[i=nextIndex(i,len)]){</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">if(e.get()==key){</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">e.clear();</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">expungeStaleEntry(i);</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">return;</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">}</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">}</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">}</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px"></span><span style="color:#993300; line-height:25px">privatevoid</span><span style="color:#3366ff; line-height:25px">replaceStaleEntry(Keykey,Objectvalue,</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">intstaleSlot){</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">Entry[]tab=table;</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">intlen=tab.length;</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">Entrye;</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">intslotToExpunge=staleSlot;</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">for(inti=prevIndex(staleSlot,len);</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">(e=tab</span><wbr style="line-height:25px"><span style="color:#3366ff; line-height:25px">)!=null;</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">i=prevIndex(i,len))</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">if(e.get()==null)</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">slotToExpunge=i;</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">for(inti=nextIndex(staleSlot,len);</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">(e=tab</span><wbr style="line-height:25px"><span style="color:#3366ff; line-height:25px">)!=null;</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">i=nextIndex(i,len)){</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">Keyk=e.get();</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">if(k==key){</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">e.value=value;</span><br style="line-height:25px"><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">tab</span><wbr style="line-height:25px"><span style="color:#3366ff; line-height:25px">=tab[staleSlot];</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">tab[staleSlot]=e;</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px"></span><span style="color:#808080; line-height:25px">//Startexpungeatprecedingstaleentryifitexists</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">if(slotToExpunge==staleSlot)</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">slotToExpunge=i;</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">cleanSomeSlots(expungeStaleEntry(slotToExpunge),len);</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">return;</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">}</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">if(k==null&amp;&amp;slotToExpunge==staleSlot)</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">slotToExpunge=i;</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">}</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">//Ifkeynotfound,putnewentryinstaleslot</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">tab[staleSlot].value=null;</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">tab[staleSlot]=newEntry(key,value);</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px"></span><span style="color:#808080; line-height:25px">//Ifthereareanyotherstaleentriesinrun,expungethem</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">if(slotToExpunge!=staleSlot)</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">cleanSomeSlots(expungeStaleEntry(slotToExpunge),len);</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">}</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px"></span><span style="color:#808080; line-height:25px">/**擦除staleSlot的Entry。<br style="line-height:25px"> *调整所有不在哈希映射位置的value的位置,让它尽量在哈希映射的位置<br style="line-height:25px"> */</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px"></span><span style="color:#993300; line-height:25px">privateint</span><span style="color:#3366ff; line-height:25px">expungeStaleEntry(intstaleSlot){</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">Entry[]tab=table;</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">intlen=tab.length;</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">tab[staleSlot].value=null;</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">tab[staleSlot]=null;</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">size--;</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">//Rehashuntilweencounternull</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">Entrye;</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">inti;</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">for(i=nextIndex(staleSlot,len);</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">(e=tab</span><wbr style="line-height:25px"><span style="color:#3366ff; line-height:25px">)!=null;</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">i=nextIndex(i,len)){</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">Keyk=e.get();</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">if(k==null){</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">e.value=null;</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">tab</span><wbr style="line-height:25px"><span style="color:#3366ff; line-height:25px">=null;</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">size--;</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">}else{</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">inth=k.hashCode&amp;(len-1);</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">if(h!=i){</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">tab</span><wbr style="line-height:25px"><span style="color:#3366ff; line-height:25px">=null;</span><br style="line-height:25px"><br style="line-height:25px"><span style="color:#808080; line-height:25px">//UnlikeKnuth6.4AlgorithmR,wemustscanuntil<br style="line-height:25px"> //nullbecausemultipleentriescouldhavebeenstale.</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">while(tab[h]!=null)</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">h=nextIndex(h,len);</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">tab[h]=e;</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">}</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">}</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">}</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">returni;</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">}</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px"></span><span style="color:#993300; line-height:25px">privateboolean</span><span style="color:#3366ff; line-height:25px">cleanSomeSlots(inti,intn){</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">booleanremoved=false;</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">Entry[]tab=table;</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">intlen=tab.length;</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">do{</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">i=nextIndex(i,len);</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">Entrye=tab</span><wbr style="line-height:25px"><span style="color:#3366ff; line-height:25px">;</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">if(e!=null&amp;&amp;e.get()==null){</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">n=len;</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">removed=true;</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">i=expungeStaleEntry(i);</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">}</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">}while((n&gt;&gt;&gt;=1)!=0);</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">returnremoved;</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">}</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">privatevoidrehash(){</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">expungeStaleEntries();</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px"></span><span style="color:#808080; line-height:25px">//Uselowerthresholdfordoublingtoavoidhysteresis</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">if(size&gt;=threshold-threshold/4)</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">resize();</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">}</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">privatevoidresize(){</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">Entry[]oldTab=table;</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">intoldLen=oldTab.length;</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">intnewLen=oldLen*2;</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">Entry[]newTab=newEntry[newLen];</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">intcount=0;</span><br style="line-height:25px"><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">for(intj=0;j&lt;oldLen;++j){</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">Entrye=oldTab[j];</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">if(e!=null){</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">Keyk=e.get();</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">if(k==null){</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">e.value=null;//HelptheGC</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">}else{</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">inth=k.hashCode&amp;(newLen-1);</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">while(newTab[h]!=null)</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">h=nextIndex(h,newLen);</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">newTab[h]=e;</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">count++;</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">}</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">}</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">}</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">setThreshold(newLen);</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">size=count;</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">table=newTab;</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">}</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px"></span><span style="color:#993300; line-height:25px">privatevoid</span><span style="color:#3366ff; line-height:25px">expungeStaleEntries(){</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">Entry[]tab=table;</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">intlen=tab.length;</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">for(intj=0;j&lt;len;j++){</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">Entrye=tab[j];</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">if(e!=null&amp;&amp;e.get()==null)</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">expungeStaleEntry(j);</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">}</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">}</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">}</span></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值