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来执行删除操作    

 

posted @ 2014-08-10 13:35  RoperLee  阅读(274)  评论(0)    收藏  举报