您的位置:首页 > 编程语言 > Java开发

Java 集合系列13之 WeakHashMap详细介绍(源码解析)和使用示例

2014-07-16 16:23 459 查看

概要

这一章,我们对WeakHashMap进行学习。
我们先对WeakHashMap有个整体认识,然后再学习它的源码,最后再通过实例来学会使用WeakHashMap。
第1部分 WeakHashMap介绍
第2部分 WeakHashMap数据结构
第3部分 WeakHashMap源码解析(基于JDK1.6.0_45)
第4部分 WeakHashMap遍历方式
第5部分 WeakHashMap示例

转载请注明出处:http://www.cnblogs.com/skywang12345/admin/EditPosts.aspx?postid=3311092

第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的构造函数

WeakHashMap共有4个构造函数,如下:

1 import java.util.Iterator;
2 import java.util.Map;
3 import java.util.WeakHashMap;
4 import java.util.Date;
5 import java.lang.ref.WeakReference;
6
7 /**
8  * @desc WeakHashMap测试程序
9  *
10  * @author skywang
11  * @email kuiwu-wang@163.com
12  */
13 public class WeakHashMapTest {
14
15     public static void main(String[] args) throws Exception {
16         testWeakHashMapAPIs();
17     }
18
19     private static void testWeakHashMapAPIs() {
20         // 初始化3个“弱键”
21         String w1 = new String("one");
22         String w2 = new String("two");
23         String w3 = new String("three");
24         // 新建WeakHashMap
25         Map wmap = new WeakHashMap();
26
27         // 添加键值对
28         wmap.put(w1, "w1");
29         wmap.put(w2, "w2");
30         wmap.put(w3, "w3");
31
32         // 打印出wmap
33         System.out.printf("\nwmap:%s\n",wmap );
34
35         // containsKey(Object key) :是否包含键key
36         System.out.printf("contains key two : %s\n",wmap.containsKey("two"));
37         System.out.printf("contains key five : %s\n",wmap.containsKey("five"));
38
39         // containsValue(Object value) :是否包含值value
40         System.out.printf("contains value 0 : %s\n",wmap.containsValue(new Integer(0)));
41
42         // remove(Object key) : 删除键key对应的键值对
43         wmap.remove("three");
44
45         System.out.printf("wmap: %s\n",wmap );
46
47
48
49         // ---- 测试 WeakHashMap 的自动回收特性 ----
50
51         // 将w1设置null。
52         // 这意味着“弱键”w1再没有被其它对象引用,调用gc时会回收WeakHashMap中与“w1”对应的键值对
53         w1 = null;
54         // 内存回收。这里,会回收WeakHashMap中与“w1”对应的键值对
55         System.gc();
56
57         // 遍历WeakHashMap
58         Iterator iter = wmap.entrySet().iterator();
59         while (iter.hasNext()) {
60             Map.Entry en = (Map.Entry)iter.next();
61             System.out.printf("next : %s - %s\n",en.getKey(),en.getValue());
62         }
63         // 打印WeakHashMap的实际大小
64         System.out.printf(" after gc WeakHashMap size:%s\n", wmap.size());
65     }
66 }


运行结果

wmap:{three=w3, one=w1, two=w2}
contains key two : true
contains key five : false
contains value 0 : false
wmap: {one=w1, two=w2}
next : two - w2
after gc WeakHashMap size:1


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐