Java中哈希表类的深入分析
《在看这部分之前必须阅读"Java中的hashCode()方法的深入剖析.doc"》
Java中的哈希表类有三类:
java.util.Hashtable
java.util.HashMap
java.util.WeakHashMap
一、三个类的功能是非常相似的,工作原理也是基本一致的
为了能够清楚的把握住哈希表类的实质,我们作如下分析:
1.哈希表类实际上就是一个容器,即由一些内存空间组成的容器,就和数组一样是用来
存储各种类型的数据的,数组和哈希表的区别就在于,数组是同下标索引来查找存储的 数据的,而哈希表是通过关键字和散列函数快速查找存储的数据的
2.在哈希表类中有两部分组成:关键字 和 要存储的数据
其中这两部分可以是任意的引用数据类型,而且只能是引用数据类型
我们通过哈希表类的成员方法put(关键字,数据),就可以将数据按照方法内部的
(关键字作用于散列函数形成的散列码)将数据存储到容器中的相应位置,这样一来
实际上我们之后就可以通过 关键字 快速找到所需的对应的数据了(get方法) 3.按照2的分析易知,我们实际上就是建立了 “关键字与所存数据间的映射”
只要给定关键字就能知道所存数据,所以得出如下的结论:
① 数组是建立起了 "整型下标int" 和 "所存数据" 之间的单向映射关系
即,只要给定一个int型的索引值就能直接获得对应的数据
② 而哈希表类中,由于关键字可以是任何引用类型的变量,所以通过哈希表
能够建立起 "任何引用型变量" 和 "所存数据" 之间的单向映射关系
这样一来,通过哈希表不仅能够摆脱 数组的 只能是 int 型和所存数据
间的关系,而且通过散列函数还能进行更加快速的查找
二.接下来通过介绍Hashtable类的成员函数,就能更加好的理解上面的内容
实例: Hashtable<String , Integer> ht = new Hashtable<String ,Integer>()
(假设 关键字是String类型的,所存的数据是 Integer型的)
1、 Hashtable类的构造方法
① public Hashtable()
实例对象的默认的容量为11,预期的装填因子默认为75% ② public Hashtable( int initialCapacity , float loadFactor)
自行设定初始容量与装填因子,我们不用担心在扩容问题,因为这些工作
程序会自动帮我们完成,而且装填因子只是一个预期值,不能保证一定达到
但是一般预设的装填因子是会影响扩容的时机的
2、数据的填装和查找
① public V put( K key , V value)
将value值存入Hashtable容器中,其中 K V 都是任意的引用数据类型
key 是 value 所对应的关键字 ; 注意:
如果在Hashtable对象中已经存在与key相同的关键字的话,那么容器中
对应处的存储的数据就会被value所替代(因为一个关键字只能对应一个
要存储的数据,否则没有实际意义,顾java做了如此规定)
如果在Hashtable 中不存在与key相同的关键字,那么直接将对应的value
存储到相应的位置,并返回null ② public V get(K key)
该方法时通过关键字key直接查找对应的数据,并返回
【通过哈希表类就会形成这样一个有趣的现象:
class A { Double key ; //将key作为对象的关键字
................
} 则我们可以创建 Hashtable<Double,A> ht = new Hashtable<Double,A>();
A a = new A();
ht.put(a.key,a);
这样就将对象a 的关键字和对象a的引用关联起来了,而我们知道引用实际就是
实例对象 a 的地址,这一点正好符合数据结构中的哈希表的实际使用状况】
3、 其他成员方法
① public void clear() 清空整个哈希表
② public boolean containsKey(Object key)
判定当前的哈希表中是否已经含有指定的关键字
③ public boolean containsValue(Object value)
public boolean contains(Object value)
这两个方法都是用来判定当前的哈希表中是否已经存在指定的value了,
不难分析,这个方法所用的时间会比较长 ④ public boolean isEmpty()
判定当前的哈希表是否为空
⑤ public V remove(Object key)
删除指定的关键字所对应的数据
⑥ public int size()
返回哈希表的元素个数
三、接下来介绍一下三个哈希表类的异同点
① java.util.Hashtable的关键字与所存的数据都不允许是null;
而java.util.HashMap 与 java.util.WeakHashMap 是都允许的
② java.util.Hashtable支持同步机制,即当有多个线程同时对类
java.util.Hashtable的实例对象进行操作时,会保证数据的正确性与
操作结果的正确性;但是其他两类却没有同步处理机制
③ java.util.WeakHashMap类(叫做弱哈希表类)会自动的按照一定的规则检查各个元
素是否“常用”如果发现某些不常用的元素存在于当前的哈下表中,那么程序就会
自动的将该元素从哈希表中删除(包括将关键字和所存数据全部删除),我们知道
如果没有引用型变量指向这些元素对应的实例的话,那么这些被删除的元素就会被
系统当做垃圾进行回收;但是java.util.Hashtable和java.util.HashMap 是没
有这种功能的,这两类只能通过成员方法remove来执行删除操作

浙公网安备 33010602011771号