首页 > 代码库 > Java 集合系列 13 WeakHashMap

Java 集合系列 13 WeakHashMap

java 集合系列目录:

Java 集合系列 01 总体框架

Java 集合系列 02 Collection架构

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

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

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

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

Java 集合系列 07 List总结(LinkedList, ArrayList等使用场景和性能分析)

Java 集合系列 08 Map架构

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

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

Java 集合系列 11 hashmap 和 hashtable 的区别

Java 集合系列 12 TreeMap

Java 集合系列 13 WeakHashMap

 

 

概述

第1部分 WeakHashMap介绍

第2部分 WeakHashMap数据结构

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

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

// 构造具有默认初始容量 (16) 和加载因子 (0.75) 的新的空 WeakHashMap()// 构造具有给定初始容量和默认加载因子 (0.75) 的新的空 WeakHashMapWeakHashMap(int capacity)// 用给定的初始容量和加载因子构造一个新的空 WeakHashMapWeakHashMap(int capacity, float loadFactor)// 包含“子Map”的构造函数WeakHashMap(Map<? extends K, ? extends V> map)

 

WeakHashMap的API

 void clear()           从此映射中移除所有映射关系。  boolean containsKey(Object key)           如果此映射对于指定的键包含映射关系,则返回 trueboolean containsValue(Object value)           如果此映射将一个或多个键映射到指定值,则返回 true。  Set<Map.Entry<K,V>> entrySet()           返回此映射所包含的映射关系的 Set 视图。  V get(Object key)           返回指定键所映射的值,如果对于该键来说,此映射不包含任何映射关系,则返回 nullboolean isEmpty()           如果此映射不包含键-值映射关系,则返回 true。  Set<K> keySet()           返回此映射所包含的键的 Set 视图。  V put(K key, V value)           关联此映射中的指定值与指定键。  void putAll(Map<? extends K,? extends V> m)           将指定映射的全部映射关系复制到此映射。  V remove(Object key)           从此弱哈希映射中移除键的映射关系(如果存在)。  int size()           返回该映射中的键-值映射关系的数目。  Collection<V> values()           返回此映射所包含的值的 Collection 视图。 

 

第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.7.0_45)