仓酷云

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 462|回复: 9
打印 上一主题 下一主题

[学习教程] 发布一篇Java汇合进修(十三) WeakHashMap具体先容(源码剖析)和利用示例 ...

[复制链接]
逍遥一派 该用户已被删除
跳转到指定楼层
楼主
发表于 2015-1-18 11:00:34 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
微软什么都提供了。你可以试想一下,如果你是新手,你是希望你点一下按钮程序就能运行那,还是想自己一点一点的组织结构,然后打包发部,调错再打包......
这一章,我们对WeakHashMap举行进修。
我们先对WeakHashMap有个全体熟悉,然后再进修它的源码,最初再经由过程实例来学会利用WeakHashMap。
第1部分WeakHashMap先容
WeakHashMap简介
WeakHashMap承继于AbstractMap,完成了Map接口。
和HashMap一样,WeakHashMap也是一个散列表,它存储的内容也是键值对(key-value)映照,并且键和值都能够是null。
不外WeakHashMap的键是“弱键”。在WeakHashMap中,当某个键不再一般利用时,会被从WeakHashMap中被主动移除。更准确地说,关于一个给定的键,其映照的存在其实不制止渣滓接纳器对该键的抛弃,这就使该键成为可停止的,被停止,然后被接纳。某个键被停止时,它对应的键值对也就从映照中无效地移除。
这个“弱键”的道理呢?大抵上就是,经由过程WeakReference和ReferenceQueue完成的。WeakHashMap的key是“弱键”,便是WeakReference范例的;ReferenceQueue是一个行列,它会保留被GC接纳的“弱键”。完成步骤是:
(01)新建WeakHashMap,将“键值对”增加到WeakHashMap中。
实践上,WeakHashMap是经由过程数组table保留Entry(键值对);每个Entry实践上是一个单向链表,即Entry是键值对链表。
(02)当某“弱键”不再被别的对象援用,并被GC接纳时。在GC接纳该“弱键”时,这个“弱键”也同时会被增加到ReferenceQueue(queue)行列中。
(03)当下一次我们必要操纵WeakHashMap时,会先同步table和queue。table中保留了全体的键值对,而queue中保留被GC接纳的键值对;同步它们,就是删除table中被GC接纳的键值对。
这就是“弱键”怎样被主动从WeakHashMap中删除的步骤了。
和HashMap一样,WeakHashMap是分歧步的。可使用Collections.synchronizedMap办法来机关同步的WeakHashMap。
WeakHashMap的承继干系以下
  1. java.lang.Object
  2. java.util.AbstractMap<K,V>
  3. java.util.WeakHashMap<K,V>
  4. publicclassWeakHashMap<K,V>
  5. extendsAbstractMap<K,V>
  6. implementsMap<K,V>{}
复制代码
WeakHashMap与Map干系以下图:

WeakHashMap的机关函数
WeakHashMap共有4个机关函数,以下:
  1. //默许机关函数。
  2. WeakHashMap()
  3. //指定“容量巨细”的机关函数
  4. WeakHashMap(intcapacity)
  5. //指定“容量巨细”和“加载因子”的机关函数
  6. WeakHashMap(intcapacity,floatloadFactor)
  7. //包括“子Map”的机关函数
  8. WeakHashMap(Map<?extendsK,?extendsV>map)
复制代码
WeakHashMap的API
  1. voidclear()
  2. Objectclone()
  3. booleancontainsKey(Objectkey)
  4. booleancontainsValue(Objectvalue)
  5. Set<Entry<K,V>>entrySet()
  6. Vget(Objectkey)
  7. booleanisEmpty()
  8. Set<K>keySet()
  9. Vput(Kkey,Vvalue)
  10. voidputAll(Map<?extendsK,?extendsV>map)
  11. Vremove(Objectkey)
  12. intsize()
  13. Collection<V>values()
复制代码

第2部分WeakHashMap源码剖析
上面对WeakHashMap的源码举行申明
  1. packagejava.util;
  2. importjava.lang.ref.WeakReference;
  3. importjava.lang.ref.ReferenceQueue;
  4. publicclassWeakHashMap<K,V>
  5. extendsAbstractMap<K,V>
  6. implementsMap<K,V>{
  7. //默许的初始容量是16,必需是2的幂。
  8. privatestaticfinalintDEFAULT_INITIAL_CAPACITY=16;
  9. //最年夜容量(必需是2的幂且小于2的30次方,传进容量过上将被这个值交换)
  10. privatestaticfinalintMAXIMUM_CAPACITY=1<<30;
  11. //默许加载因子
  12. privatestaticfinalfloatDEFAULT_LOAD_FACTOR=0.75f;
  13. //存储数据的Entry数组,长度是2的幂。
  14. //WeakHashMap是接纳拉链法完成的,每个Entry实质上是一个单向链表
  15. privateEntry[]table;
  16. //WeakHashMap的巨细,它是WeakHashMap保留的键值对的数目
  17. privateintsize;
  18. //WeakHashMap的阈值,用于判别是不是必要调剂WeakHashMap的容量(threshold=容量*加载因子)
  19. privateintthreshold;
  20. //加载因籽实际巨细
  21. privatefinalfloatloadFactor;
  22. //queue保留的是“已被GC扫除”的“弱援用的键”。
  23. //弱援用和ReferenceQueue是团结利用的:假如弱援用所援用的对象被渣滓接纳,Java假造机就会把这个弱援用到场到与之联系关系的援用行列中
  24. privatefinalReferenceQueue<K>queue=newReferenceQueue<K>();
  25. //WeakHashMap被改动的次数
  26. privatevolatileintmodCount;
  27. //指定“容量巨细”和“加载因子”的机关函数
  28. publicWeakHashMap(intinitialCapacity,floatloadFactor){
  29. if(initialCapacity<0)
  30. thrownewIllegalArgumentException("IllegalInitialCapacity:"+
  31. initialCapacity);
  32. //WeakHashMap的最年夜容量只能是MAXIMUM_CAPACITY
  33. if(initialCapacity>MAXIMUM_CAPACITY)
  34. initialCapacity=MAXIMUM_CAPACITY;
  35. if(loadFactor<=0||Float.isNaN(loadFactor))
  36. thrownewIllegalArgumentException("IllegalLoadfactor:"+
  37. loadFactor);
  38. //找出“年夜于initialCapacity”的最小的2的幂
  39. intcapacity=1;
  40. while(capacity<initialCapacity)
  41. capacity<<=1;
  42. //创立Entry数组,用来保留数据
  43. table=newEntry[capacity];
  44. //设置“加载因子”
  45. this.loadFactor=loadFactor;
  46. //设置“WeakHashMap阈值”,当WeakHashMap中存储数据的数目到达threshold时,就必要将WeakHashMap的容量更加。
  47. threshold=(int)(capacity*loadFactor);
  48. }
  49. //指定“容量巨细”的机关函数
  50. publicWeakHashMap(intinitialCapacity){
  51. this(initialCapacity,DEFAULT_LOAD_FACTOR);
  52. }
  53. //默许机关函数。
  54. publicWeakHashMap(){
  55. this.loadFactor=DEFAULT_LOAD_FACTOR;
  56. threshold=(int)(DEFAULT_INITIAL_CAPACITY);
  57. table=newEntry[DEFAULT_INITIAL_CAPACITY];
  58. }
  59. //包括“子Map”的机关函数
  60. publicWeakHashMap(Map<?extendsK,?extendsV>m){
  61. this(Math.max((int)(m.size()/DEFAULT_LOAD_FACTOR)+1,16),
  62. DEFAULT_LOAD_FACTOR);
  63. //将m中的全体元素逐一增加到WeakHashMap中
  64. putAll(m);
  65. }
  66. //键为null的mask值。
  67. //由于WeakReference中同意“null的key”,若间接拔出“null的key”,将其看成弱援用时,会被删除。
  68. //因而,这里关于“key为null”的清空,都一致交换为“key为NULL_KEY”,“NULL_KEY”是“静态的final常量”。
  69. privatestaticfinalObjectNULL_KEY=newObject();
  70. //对“null的key”举行特别处置
  71. privatestaticObjectmaskNull(Objectkey){
  72. return(key==null?NULL_KEY:key);
  73. }
  74. //复原对“null的key”的特别处置
  75. privatestatic<K>KunmaskNull(Objectkey){
  76. return(K)(key==NULL_KEY?null:key);
  77. }
  78. //判别“x”和“y”是不是相称
  79. staticbooleaneq(Objectx,Objecty){
  80. returnx==y||x.equals(y);
  81. }
  82. //前往索引值
  83. //h&(length-1)包管前往值的小于length
  84. staticintindexFor(inth,intlength){
  85. returnh&(length-1);
  86. }
  87. //清空table中无用键值对。道理以下:
  88. //(01)当WeakHashMap中某个“弱援用的key”因为没有再被援用而被GC发出时,
  89. //被接纳的“该弱援用key”也被会被增加到"ReferenceQueue(queue)"中。
  90. //(02)当我们实行expungeStaleEntries时,
  91. //就遍历"ReferenceQueue(queue)"中的一切key
  92. //然后就在“WeakReference的table”中删除与“ReferenceQueue(queue)中key”对应的键值对
  93. privatevoidexpungeStaleEntries(){
  94. Entry<K,V>e;
  95. while((e=(Entry<K,V>)queue.poll())!=null){
  96. inth=e.hash;
  97. inti=indexFor(h,table.length);
  98. Entry<K,V>prev=table[i];
  99. Entry<K,V>p=prev;
  100. while(p!=null){
  101. Entry<K,V>next=p.next;
  102. if(p==e){
  103. if(prev==e)
  104. table[i]=next;
  105. else
  106. prev.next=next;
  107. e.next=null;//HelpGC
  108. e.value=null;//""
  109. size--;
  110. break;
  111. }
  112. prev=p;
  113. p=next;
  114. }
  115. }
  116. }
  117. //猎取WeakHashMap的table(寄存键值对的数组)
  118. privateEntry[]getTable(){
  119. //删除table中“已被GC接纳的key对应的键值对”
  120. expungeStaleEntries();
  121. returntable;
  122. }
  123. //猎取WeakHashMap的实践巨细
  124. publicintsize(){
  125. if(size==0)
  126. return0;
  127. //删除table中“已被GC接纳的key对应的键值对”
  128. expungeStaleEntries();
  129. returnsize;
  130. }
  131. publicbooleanisEmpty(){
  132. returnsize()==0;
  133. }
  134. //猎取key对应的value
  135. publicVget(Objectkey){
  136. Objectk=maskNull(key);
  137. //猎取key的hash值。
  138. inth=HashMap.hash(k.hashCode());
  139. Entry[]tab=getTable();
  140. intindex=indexFor(h,tab.length);
  141. Entry<K,V>e=tab[index];
  142. //在“该hash值对应的链表”上查找“键值即是key”的元素
  143. while(e!=null){
  144. if(e.hash==h&&eq(k,e.get()))
  145. returne.value;
  146. e=e.next;
  147. }
  148. returnnull;
  149. }
  150. //WeakHashMap是不是包括key
  151. publicbooleancontainsKey(Objectkey){
  152. returngetEntry(key)!=null;
  153. }
  154. //前往“键为key”的键值对
  155. Entry<K,V>getEntry(Objectkey){
  156. Objectk=maskNull(key);
  157. inth=HashMap.hash(k.hashCode());
  158. Entry[]tab=getTable();
  159. intindex=indexFor(h,tab.length);
  160. Entry<K,V>e=tab[index];
  161. while(e!=null&&!(e.hash==h&&eq(k,e.get())))
  162. e=e.next;
  163. returne;
  164. }
  165. //将“key-value”增加到WeakHashMap中
  166. publicVput(Kkey,Vvalue){
  167. Kk=(K)maskNull(key);
  168. inth=HashMap.hash(k.hashCode());
  169. Entry[]tab=getTable();
  170. inti=indexFor(h,tab.length);
  171. for(Entry<K,V>e=tab[i];e!=null;e=e.next){
  172. //若“该key”对应的键值对已存在,则用新的value代替旧的value。然前进出!
  173. if(h==e.hash&&eq(k,e.get())){
  174. VoldValue=e.value;
  175. if(value!=oldValue)
  176. e.value=value;
  177. returnoldValue;
  178. }
  179. }
  180. //若“该key”对应的键值对不存在于WeakHashMap中,则将“key-value”增加到table中
  181. modCount++;
  182. Entry<K,V>e=tab[i];
  183. tab[i]=newEntry<K,V>(k,value,queue,h,e);
  184. if(++size>=threshold)
  185. resize(tab.length*2);
  186. returnnull;
  187. }
  188. //从头调剂WeakHashMap的巨细,newCapacity是调剂后的单元
  189. voidresize(intnewCapacity){
  190. Entry[]oldTable=getTable();
  191. intoldCapacity=oldTable.length;
  192. if(oldCapacity==MAXIMUM_CAPACITY){
  193. threshold=Integer.MAX_VALUE;
  194. return;
  195. }
  196. //新建一个newTable,将“旧的table”的全体元素增加到“新的newTable”中,
  197. //然后,将“新的newTable”赋值给“旧的table”。
  198. Entry[]newTable=newEntry[newCapacity];
  199. transfer(oldTable,newTable);
  200. table=newTable;
  201. if(size>=threshold/2){
  202. threshold=(int)(newCapacity*loadFactor);
  203. }else{
  204. //删除table中“已被GC接纳的key对应的键值对”
  205. expungeStaleEntries();
  206. transfer(newTable,oldTable);
  207. table=oldTable;
  208. }
  209. }
  210. //将WeakHashMap中的全体元素都增加到newTable中
  211. privatevoidtransfer(Entry[]src,Entry[]dest){
  212. for(intj=0;j<src.length;++j){
  213. Entry<K,V>e=src[j];
  214. src[j]=null;
  215. while(e!=null){
  216. Entry<K,V>next=e.next;
  217. Objectkey=e.get();
  218. if(key==null){
  219. e.next=null;//HelpGC
  220. e.value=null;//""
  221. size--;
  222. }else{
  223. inti=indexFor(e.hash,dest.length);
  224. e.next=dest[i];
  225. dest[i]=e;
  226. }
  227. e=next;
  228. }
  229. }
  230. }
  231. //将"m"的全体元素都增加到WeakHashMap中
  232. publicvoidputAll(Map<?extendsK,?extendsV>m){
  233. intnumKeysToBeAdded=m.size();
  234. if(numKeysToBeAdded==0)
  235. return;
  236. //盘算容量是不是充足,
  237. //若“以后实践容量<必要的容量”,则将容量x2。
  238. if(numKeysToBeAdded>threshold){
  239. inttargetCapacity=(int)(numKeysToBeAdded/loadFactor+1);
  240. if(targetCapacity>MAXIMUM_CAPACITY)
  241. targetCapacity=MAXIMUM_CAPACITY;
  242. intnewCapacity=table.length;
  243. while(newCapacity<targetCapacity)
  244. newCapacity<<=1;
  245. if(newCapacity>table.length)
  246. resize(newCapacity);
  247. }
  248. //将“m”中的元素逐一增加到WeakHashMap中。
  249. for(Map.Entry<?extendsK,?extendsV>e:m.entrySet())
  250. put(e.getKey(),e.getValue());
  251. }
  252. //删除“键为key”元素
  253. publicVremove(Objectkey){
  254. Objectk=maskNull(key);
  255. //猎取哈希值。
  256. inth=HashMap.hash(k.hashCode());
  257. Entry[]tab=getTable();
  258. inti=indexFor(h,tab.length);
  259. Entry<K,V>prev=tab[i];
  260. Entry<K,V>e=prev;
  261. //删除链表中“键为key”的元素
  262. //实质是“删除单向链表中的节点”
  263. while(e!=null){
  264. Entry<K,V>next=e.next;
  265. if(h==e.hash&&eq(k,e.get())){
  266. modCount++;
  267. size--;
  268. if(prev==e)
  269. tab[i]=next;
  270. else
  271. prev.next=next;
  272. returne.value;
  273. }
  274. prev=e;
  275. e=next;
  276. }
  277. returnnull;
  278. }
  279. //删除“键值对”
  280. Entry<K,V>removeMapping(Objecto){
  281. if(!(oinstanceofMap.Entry))
  282. returnnull;
  283. Entry[]tab=getTable();
  284. Map.Entryentry=(Map.Entry)o;
  285. Objectk=maskNull(entry.getKey());
  286. inth=HashMap.hash(k.hashCode());
  287. inti=indexFor(h,tab.length);
  288. Entry<K,V>prev=tab[i];
  289. Entry<K,V>e=prev;
  290. //删除链表中的“键值对e”
  291. //实质是“删除单向链表中的节点”
  292. while(e!=null){
  293. Entry<K,V>next=e.next;
  294. if(h==e.hash&&e.equals(entry)){
  295. modCount++;
  296. size--;
  297. if(prev==e)
  298. tab[i]=next;
  299. else
  300. prev.next=next;
  301. returne;
  302. }
  303. prev=e;
  304. e=next;
  305. }
  306. returnnull;
  307. }
  308. //清空WeakHashMap,将一切的元素设为null
  309. publicvoidclear(){
  310. while(queue.poll()!=null)
  311. ;
  312. modCount++;
  313. Entry[]tab=table;
  314. for(inti=0;i<tab.length;++i)
  315. tab[i]=null;
  316. size=0;
  317. while(queue.poll()!=null)
  318. ;
  319. }
  320. //是不是包括“值为value”的元素
  321. publicbooleancontainsValue(Objectvalue){
  322. //若“value为null”,则挪用containsNullValue()查找
  323. if(value==null)
  324. returncontainsNullValue();
  325. //若“value不为null”,则查找WeakHashMap中是不是有值为value的节点。
  326. Entry[]tab=getTable();
  327. for(inti=tab.length;i-->0;)
  328. for(Entrye=tab[i];e!=null;e=e.next)
  329. if(value.equals(e.value))
  330. returntrue;
  331. returnfalse;
  332. }
  333. //是不是包括null值
  334. privatebooleancontainsNullValue(){
  335. Entry[]tab=getTable();
  336. for(inti=tab.length;i-->0;)
  337. for(Entrye=tab[i];e!=null;e=e.next)
  338. if(e.value==null)
  339. returntrue;
  340. returnfalse;
  341. }
  342. //Entry是单向链表。
  343. //它是“WeakHashMap链式存储法”对应的链表。
  344. //它完成了Map.Entry接口,即完成getKey(),getValue(),setValue(Vvalue),equals(Objecto),hashCode()这些函数
  345. privatestaticclassEntry<K,V>extendsWeakReference<K>implementsMap.Entry<K,V>{
  346. privateVvalue;
  347. privatefinalinthash;
  348. //指向下一个节点
  349. privateEntry<K,V>next;
  350. //机关函数。
  351. Entry(Kkey,Vvalue,
  352. ReferenceQueue<K>queue,
  353. inthash,Entry<K,V>next){
  354. super(key,queue);
  355. this.value=value;
  356. this.hash=hash;
  357. this.next=next;
  358. }
  359. publicKgetKey(){
  360. returnWeakHashMap.<K>unmaskNull(get());
  361. }
  362. publicVgetValue(){
  363. returnvalue;
  364. }
  365. publicVsetValue(VnewValue){
  366. VoldValue=value;
  367. value=newValue;
  368. returnoldValue;
  369. }
  370. //判别两个Entry是不是相称
  371. //若两个Entry的“key”和“value”都相称,则前往true。
  372. //不然,前往false
  373. publicbooleanequals(Objecto){
  374. if(!(oinstanceofMap.Entry))
  375. returnfalse;
  376. Map.Entrye=(Map.Entry)o;
  377. Objectk1=getKey();
  378. Objectk2=e.getKey();
  379. if(k1==k2||(k1!=null&&k1.equals(k2))){
  380. Objectv1=getValue();
  381. Objectv2=e.getValue();
  382. if(v1==v2||(v1!=null&&v1.equals(v2)))
  383. returntrue;
  384. }
  385. returnfalse;
  386. }
  387. //完成hashCode()
  388. publicinthashCode(){
  389. Objectk=getKey();
  390. Objectv=getValue();
  391. return((k==null?0:k.hashCode())^
  392. (v==null?0:v.hashCode()));
  393. }
  394. publicStringtoString(){
  395. returngetKey()+"="+getValue();
  396. }
  397. }
  398. //HashIterator是WeakHashMap迭代器的笼统出来的父类,完成了大众了函数。
  399. //它包括“key迭代器(KeyIterator)”、“Value迭代器(ValueIterator)”和“Entry迭代器(EntryIterator)”3个子类。
  400. privateabstractclassHashIterator<T>implementsIterator<T>{
  401. //以后索引
  402. intindex;
  403. //以后元素
  404. Entry<K,V>entry=null;
  405. //上一次前往元素
  406. Entry<K,V>lastReturned=null;
  407. //expectedModCount用于完成fast-fail机制。
  408. intexpectedModCount=modCount;
  409. //下一个键(强援用)
  410. ObjectnextKey=null;
  411. //以后键(强援用)
  412. ObjectcurrentKey=null;
  413. //机关函数
  414. HashIterator(){
  415. index=(size()!=0?table.length:0);
  416. }
  417. //是不是存鄙人一个元素
  418. publicbooleanhasNext(){
  419. Entry[]t=table;
  420. //一个Entry就是一个单向链表
  421. //若该Entry的下一个节点不为空,就将next指向下一个节点;
  422. //不然,将next指向下一个链表(也是下一个Entry)的不为null的节点。
  423. while(nextKey==null){
  424. Entry<K,V>e=entry;
  425. inti=index;
  426. while(e==null&&i>0)
  427. e=t[--i];
  428. entry=e;
  429. index=i;
  430. if(e==null){
  431. currentKey=null;
  432. returnfalse;
  433. }
  434. nextKey=e.get();//holdontokeyinstrongref
  435. if(nextKey==null)
  436. entry=entry.next;
  437. }
  438. returntrue;
  439. }
  440. //猎取下一个元素
  441. protectedEntry<K,V>nextEntry(){
  442. if(modCount!=expectedModCount)
  443. thrownewConcurrentModificationException();
  444. if(nextKey==null&&!hasNext())
  445. thrownewNoSuchElementException();
  446. lastReturned=entry;
  447. entry=entry.next;
  448. currentKey=nextKey;
  449. nextKey=null;
  450. returnlastReturned;
  451. }
  452. //删除以后元素
  453. publicvoidremove(){
  454. if(lastReturned==null)
  455. thrownewIllegalStateException();
  456. if(modCount!=expectedModCount)
  457. thrownewConcurrentModificationException();
  458. WeakHashMap.this.remove(currentKey);
  459. expectedModCount=modCount;
  460. lastReturned=null;
  461. currentKey=null;
  462. }
  463. }
  464. //value的迭代器
  465. privateclassValueIteratorextendsHashIterator<V>{
  466. publicVnext(){
  467. returnnextEntry().value;
  468. }
  469. }
  470. //key的迭代器
  471. privateclassKeyIteratorextendsHashIterator<K>{
  472. publicKnext(){
  473. returnnextEntry().getKey();
  474. }
  475. }
  476. //Entry的迭代器
  477. privateclassEntryIteratorextendsHashIterator<Map.Entry<K,V>>{
  478. publicMap.Entry<K,V>next(){
  479. returnnextEntry();
  480. }
  481. }
  482. //WeakHashMap的Entry对应的汇合
  483. privatetransientSet<Map.Entry<K,V>>entrySet=null;
  484. //前往“key的汇合”,实践上前往一个“KeySet对象”
  485. publicSet<K>keySet(){
  486. Set<K>ks=keySet;
  487. return(ks!=null?ks:(keySet=newKeySet()));
  488. }
  489. //Key对应的汇合
  490. //KeySet承继于AbstractSet,申明该汇合中没有反复的Key。
  491. privateclassKeySetextendsAbstractSet<K>{
  492. publicIterator<K>iterator(){
  493. returnnewKeyIterator();
  494. }
  495. publicintsize(){
  496. returnWeakHashMap.this.size();
  497. }
  498. publicbooleancontains(Objecto){
  499. returncontainsKey(o);
  500. }
  501. publicbooleanremove(Objecto){
  502. if(containsKey(o)){
  503. WeakHashMap.this.remove(o);
  504. returntrue;
  505. }
  506. else
  507. returnfalse;
  508. }
  509. publicvoidclear(){
  510. WeakHashMap.this.clear();
  511. }
  512. }
  513. //前往“value汇合”,实践上前往的是一个Values对象
  514. publicCollection<V>values(){
  515. Collection<V>vs=values;
  516. return(vs!=null?vs:(values=newValues()));
  517. }
  518. //“value汇合”
  519. //Values承继于AbstractCollection,分歧于“KeySet承继于AbstractSet”,
  520. //Values中的元素可以反复。由于分歧的key能够指向不异的value。
  521. privateclassValuesextendsAbstractCollection<V>{
  522. publicIterator<V>iterator(){
  523. returnnewValueIterator();
  524. }
  525. publicintsize(){
  526. returnWeakHashMap.this.size();
  527. }
  528. publicbooleancontains(Objecto){
  529. returncontainsValue(o);
  530. }
  531. publicvoidclear(){
  532. WeakHashMap.this.clear();
  533. }
  534. }
  535. //前往“WeakHashMap的Entry汇合”
  536. //它实践是前往一个EntrySet对象
  537. publicSet<Map.Entry<K,V>>entrySet(){
  538. Set<Map.Entry<K,V>>es=entrySet;
  539. returnes!=null?es:(entrySet=newEntrySet());
  540. }
  541. //EntrySet对应的汇合
  542. //EntrySet承继于AbstractSet,申明该汇合中没有反复的EntrySet。
  543. privateclassEntrySetextendsAbstractSet<Map.Entry<K,V>>{
  544. publicIterator<Map.Entry<K,V>>iterator(){
  545. returnnewEntryIterator();
  546. }
  547. //是不是包括“值(o)”
  548. publicbooleancontains(Objecto){
  549. if(!(oinstanceofMap.Entry))
  550. returnfalse;
  551. Map.Entrye=(Map.Entry)o;
  552. Objectk=e.getKey();
  553. Entrycandidate=getEntry(e.getKey());
  554. returncandidate!=null&&candidate.equals(e);
  555. }
  556. //删除“值(o)”
  557. publicbooleanremove(Objecto){
  558. returnremoveMapping(o)!=null;
  559. }
  560. //前往WeakHashMap的巨细
  561. publicintsize(){
  562. returnWeakHashMap.this.size();
  563. }
  564. //清空WeakHashMap
  565. publicvoidclear(){
  566. WeakHashMap.this.clear();
  567. }
  568. //拷贝函数。将WeakHashMap中的全体元素都拷贝到List中
  569. privateList<Map.Entry<K,V>>deepCopy(){
  570. List<Map.Entry<K,V>>list=newArrayList<Map.Entry<K,V>>(size());
  571. for(Map.Entry<K,V>e:this)
  572. list.add(newAbstractMap.SimpleEntry<K,V>(e));
  573. returnlist;
  574. }
  575. //前往Entry对应的Object[]数组
  576. publicObject[]toArray(){
  577. returndeepCopy().toArray();
  578. }
  579. //前往Entry对应的T[]数组(T[]我们新建数组时,界说的数组范例)
  580. public<T>T[]toArray(T[]a){
  581. returndeepCopy().toArray(a);
  582. }
  583. }
  584. }
复制代码
检察本栏目更多出色内容:http://www.bianceng.cn/Programming/Java/
申明:
<p>
对于一个大型项目,如果用java来作,可能需要9个月,并且可能需要翻阅10本以上的书,但如果用ruby来作,3个月,3本书就足够了,而.net也不过3,4本书足以,这就是区别。
透明 该用户已被删除
沙发
发表于 2015-1-20 12:34:29 | 只看该作者
其实说这种话的人就如当年小日本号称“三个月拿下中国”一样大言不惭。不是Tomjava泼你冷水,你现在只是学到了Java的骨架,却还没有学到Java的精髓。接下来你得研究设计模式了。
金色的骷髅 该用户已被删除
板凳
发表于 2015-1-24 16:08:35 | 只看该作者
当然你也可以参加一些开源项目,一方面可以提高自己,另一方面也是为中国软件事业做贡献嘛!开发者在互联网上用CVS合作开发,用QQ,MSN,E-mail讨论联系,天南海北的程序员分散在各地却同时开发同一个软件,是不是很有意思呢?
深爱那片海 该用户已被删除
地板
发表于 2015-1-30 17:37:54 | 只看该作者
应用在电视机、电话、闹钟、烤面包机等家用电器的控制和通信。由于这些智能化家电的市场需求没有预期的高,Sun公司放弃了该项计划。随着1990年代互联网的发展
只想知道 该用户已被删除
5#
发表于 2015-2-6 14:34:18 | 只看该作者
是一种突破用户端机器环境和CPU
莫相离 该用户已被删除
6#
发表于 2015-2-16 13:57:49 | 只看该作者
J2SE开发桌面应用软件比起 VC,VB,DEPHI这些传统开发语言来说,优势好象并不明显。J2ME对于初学者来说,好象又有点深奥,而且一般开发者很难有开发环境。
老尸 该用户已被删除
7#
发表于 2015-3-5 06:06:09 | 只看该作者
是一种突破用户端机器环境和CPU
柔情似水 该用户已被删除
8#
发表于 2015-3-11 23:37:44 | 只看该作者
Java语言支持Internet应用的开发,在基本的Java应用编程接口中有一个网络应用编程接口(java net),它提供了用于网络应用编程的类库,包括URL、URLConnection、Socket、ServerSocket等。Java的RMI(远程方法激活)机制也是开发分布式应用的重要手段。
若天明 该用户已被删除
9#
发表于 2015-3-19 16:10:07 | 只看该作者
不过,每次的执行编译后的字节码需要消耗一定的时间,这同时也在一定程度上降低了 Java 程序的运行效率。
爱飞 该用户已被删除
10#
发表于 2015-3-29 00:53:14 | 只看该作者
Java 不同于一般的编译执行计算机语言和解释执行计算机语言。它首先将源代码编译成二进制字节码(bytecode),然后依赖各种不同平台上的虚拟机来解释执行字节码。从而实现了“一次编译、到处执行”的跨平台特性。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|仓酷云 鄂ICP备14007578号-2

GMT+8, 2024-12-23 21:06

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表