第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个构造函数,如下:

复制代码 // 默认构造函数。 WeakHashMap()

// 指定“容量大小”的构造函数 WeakHashMap(int capacity)

// 指定“容量大小”和“加载因子”的构造函数 WeakHashMap(int capacity, float loadFactor)

// 包含“子Map”的构造函数 WeakHashMap(Map<? extends K, ? extends V> map) 复制代码

WeakHashMap的API

复制代码 void clear() Object clone() boolean containsKey(Object key) boolean containsValue(Object value) Set<Entry<K, V>> entrySet() V get(Object key) boolean isEmpty() Set keySet() V put(K key, V value) void putAll(Map<? extends K, ? extends V> map) V remove(Object key) int size() Collection values() 复制代码

第2部分 WeakHashMap数据结构 WeakHashMap的继承关系如下

复制代码 java.lang.Object ↳ java.util.AbstractMap<K, V> ↳ java.util.WeakHashMap<K, V>

public class WeakHashMap<K,V> extends AbstractMap<K,V> implements Map<K,V> {} 复制代码

WeakHashMap与Map关系如下图:

从图中可以看出: (01) WeakHashMap继承于AbstractMap,并且实现了Map接口。 (02) WeakHashMap是哈希表,但是它的键是"弱键"。WeakHashMap中保护几个重要的成员变量:table, size, threshold, loadFactor, modCount, queue。   table是一个Entry[]数组类型,而Entry实际上就是一个单向链表。哈希表的"key-value键值对"都是存储在Entry数组中的。   size是Hashtable的大小,它是Hashtable保存的键值对的数量。   threshold是Hashtable的阈值,用于判断是否需要调整Hashtable的容量。threshold的值="容量*加载因子"。   loadFactor就是加载因子。   modCount是用来实现fail-fast机制的   queue保存的是“已被GC清除”的“弱引用的键”。

第3部分 WeakHashMap源码解析(基于JDK1.6.0_45) 下面对WeakHashMap的源码进行说明

View Code 说明:WeakHashMap和HashMap都是通过"拉链法"实现的散列表。它们的源码绝大部分内容都一样,这里就只是对它们不同的部分就是说明。

WeakReference是“弱键”实现的哈希表。它这个“弱键”的目的就是:实现对“键值对”的动态回收。当“弱键”不再被使用到时,GC会回收它,WeakReference也会将“弱键”对应的键值对删除。
“弱键”是一个“弱引用(WeakReference)”,在Java中,WeakReference和ReferenceQueue 是联合使用的。在WeakHashMap中亦是如此:如果弱引用所引用的对象被垃圾回收,Java虚拟机就会把这个弱引用加入到与之关联的引用队列中。 接着,WeakHashMap会根据“引用队列”,来删除“WeakHashMap中已被GC回收的‘弱键’对应的键值对”。
另外,理解上面思想的重点是通过 expungeStaleEntries() 函数去理解。
复制代码

第4部分 WeakHashMap遍历方式 4.1 遍历WeakHashMap的键值对

第一步:根据entrySet()获取WeakHashMap的“键值对”的Set集合。 第二步:通过Iterator迭代器遍历“第一步”得到的集合。

复制代码 // 假设map是WeakHashMap对象 // map中的key是String类型,value是Integer类型 Integer integ = null; Iterator iter = map.entrySet().iterator(); while(iter.hasNext()) { Map.Entry entry = (Map.Entry)iter.next(); // 获取key key = (String)entry.getKey(); // 获取value integ = (Integer)entry.getValue(); } 复制代码

4.2 遍历WeakHashMap的键

第一步:根据keySet()获取WeakHashMap的“键”的Set集合。 第二步:通过Iterator迭代器遍历“第一步”得到的集合。

复制代码 // 假设map是WeakHashMap对象 // map中的key是String类型,value是Integer类型 String key = null; Integer integ = null; Iterator iter = map.keySet().iterator(); while (iter.hasNext()) { // 获取key key = (String)iter.next(); // 根据key,获取value integ = (Integer)map.get(key); } 复制代码

4.3 遍历WeakHashMap的值

第一步:根据value()获取WeakHashMap的“值”的集合。 第二步:通过Iterator迭代器遍历“第一步”得到的集合。

复制代码 // 假设map是WeakHashMap对象 // map中的key是String类型,value是Integer类型 Integer value = null; Collection c = map.values(); Iterator iter= c.iterator(); while (iter.hasNext()) { value = (Integer)iter.next(); } 复制代码 WeakHashMap遍历测试程序如下:

View Code

第5部分 WeakHashMap示例 下面通过实例来学习如何使用WeakHashMap

View Code 运行结果:

复制代码 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 复制代码

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

  1. Java 集合系列03之 ArrayList详细介绍(源码解析)和使用示例

    转载自  Java 集合系列03之 ArrayList详细介绍(源码解析)和使用示例 第1部分 ArrayList介绍 ArrayList简介 ArrayList 是一个数组队列,相当于 动态数组.与 ...

  2. Java 集合系列16之 HashSet详细介绍(源码解析)和使用示例

    概要 这一章,我们对HashSet进行学习. 我们先对HashSet有个整体认识,然后再学习它的源码,最后再通过实例来学会使用HashSet.内容包括: 第1部分 HashSet介绍 第2部分 Has ...

  3. Java 集合系列17之 TreeSet详细介绍(源码解析)和使用示例

    转载 http://www.cnblogs.com/skywang12345/p/3311268.html 转载于:https://www.cnblogs.com/lizhouwei/p/917493 ...

  4. Java 集合系列07之 Stack详细介绍(源码解析)和使用示例

    转载 http://www.cnblogs.com/skywang12345/p/3308852.html 转载于:https://www.cnblogs.com/lizhouwei/p/916225 ...

  5. Java 集合系列12之 Hashtable详细介绍(源码解析)和使用示例

    转载 http://www.cnblogs.com/skywang12345/p/3310887.html 转载于:https://www.cnblogs.com/lizhouwei/p/916901 ...

  6. 吊打java面试官之 Hashtable详细介绍(源码解析)和使用示例

    概要 前一章,我们学习了HashMap.这一章,我们对Hashtable进行学习. 我们先对Hashtable有个整体认识,然后再学习它的源码,最后再通过实例来学会使用Hashtable. 第1部分 ...

  7. 吊打面试官:Vector详细介绍(源码解析)和使用示例

    概要 学完ArrayList和LinkedList之后,我们接着学习Vector.学习方式还是和之前一样,先对Vector有个整体认识,然后再学习它的源码:最后再通过实例来学会使用它. 第1部分 Ve ...

  8. Java 集合系列(4): LinkedList源码深入解析1

    戳上面的蓝字关注我们哦! 精彩内容 精选java等全套视频教程 精选java电子图书 大数据视频教程精选 java项目练习精选 概要 前面,我们已经学习了ArrayList,并了解了fail-fast ...

  9. Java 集合系列(2): ArrayList源码深入解析和使用示例

    戳上面的蓝字关注我们哦! 精彩内容 精选java等全套视频教程 精选java电子图书 大数据视频教程精选 java项目练习精选 概要 上一章,我们学习了Collection的架构.这一章开始,我们对C ...

  10. Java 集合系列(4): LinkedList源码深入解析2

    戳上面的蓝字关注我们哦! 精彩内容 精选java等全套视频教程 精选java电子图书 大数据视频教程精选 java项目练习精选 第4部分 LinkedList遍历方式 LinkedList遍历方式 L ...

最新文章

  1. 64位系统上使用*** Client端
  2. java的for循环的几种写法
  3. Failed to initiate service connection to simulator
  4. nessus重置密码
  5. 【2019浙江省赛 - K 】Strings in the Pocket(马拉车,思维)
  6. hdfs如何查找指定目录是否文件_hadoop实战教程-HDFS文件系统如何查看文件对应的block...
  7. 大航海北斗星导航系统V1.10
  8. JS对数组对象按照某个字段进行排序
  9. java 学生考勤系统(三、签到功能)
  10. 逆向爬虫11 selenium基础
  11. 计算机英语单词怎么读,英语单词read怎么读,read的音标是什么,read是什么意思 - 音标网...
  12. SQL数据库无法附加
  13. HowToDoIt 开源框架爱好者组织发布第一份项目总结
  14. 头像照片汇聚logo视频片头ae竖屏模板
  15. 简单的网页登录注册页面
  16. linux下无线网卡测试,Linux C程序如何检测WIFI无线USB网卡是否可用?
  17. 系统平台:新店如何打造爆款
  18. python循环批量读取tushare财务数据
  19. 联想ideapad15s安装(烧录)ubuntu操作系统(双系统)
  20. zte手机android手机怎么刷机,中兴ZTE A2020 Pro刷机教程,卡刷升级更新官方固件系统包...

热门文章

  1. MySQL数据库迁移注意点
  2. DHCP服务原理(转载)
  3. React Native 入门第一篇
  4. 小程序的网络请求封装
  5. Mysql 存储类型范围
  6. Layui第三方扩展LAY_EXCEL自定义导出数据类型
  7. Layer表格列根据配置动态显示
  8. Mysql 按 create_time 排序导致的问题
  9. Layer 引入自定义模块
  10. 龙芯OpenJDK更新策略:没必要跟进小版本,最后大版本更新