HashMap和HashTable的区别

 

     HashTable类是通过数组+链表(单节点)实现的map集合,继承自Dictionary类,实现了三个接口,分别是Map,Cloneable和java.io.Serializable,
     在初始化时有2个重要的参数,初始容量(默认11)和负载因子是0.75,
     Hashtable直接使用对象的hashCode值,使用除留余数发来获得最终的位置,     
     
     put方法
        put方法的主要逻辑如下:
        先获取synchronized锁,如果value和key为null,直接抛出空指针异常,如果不为null,则获取key的hashcode值,
        然后让hashcode值 & 0xFFFFFFF(int的最大值) 做按位与运算,将结果与数组的长度取模,得到插入元素位置的索引
        而后通过索引获取对应Entry节点,如果节点为null,直接将值存入,如果不为null,则判断当前传入的hash值与entry的
        hash值是否一致,equals是否相等,如果相等,则将新值替换成旧值,如果不相等,则将当前Entry节点赋值给next节点,将
        新的值存入entry节点.
        在添加时同样会判断当前entry数组中的长度是否大于了扩容阀值,会调用rehash()方法进行扩容
                
    get方法
        先获取synchronized锁,通过key的hash值做按位与运算,将结果与数组的长度取模,得到插入元素位置的索引
        在对应位置的链表中寻找具有相同hash和key的节点,返回节点的value。
        如果遍历结束都没有找到节点,则返回null。
      
    HashMap和HashTable的区别:    
    1.继承上
         Hashtable继承自Dictionary类,HashMap继承自AbstractMap类
         但二者都实现了Map接口
    2.构造上
        Hashtable的默认容量为11,默认负载因子为0.75,Hashtable的容量可以为任意整数,最小值为1
        HashMap默认容量为16,默认负载因子也是0.75,而HashMap的容量始终为2的n次方
        
    3.线程安全性上
        Hashtable是线程安全的,它里面的方法都加了synchronized
        HashMap是线程不安全的,效率高,会报并发修改异常
    4.是否为null上
        HashMap允许null可以作为键,但是能有一个
        Hashtable中key和value都不允许为null,会报空指针异常
    5.索引效率上的不同
         hashtable使用的是key的hashcode值做按位与运算,目的是将值转化成正值,因为hash值有可能为负,而后再对数组长度取模运算
         hashmap是将key再进行hashcode取值,将值右移16位后做^(按位异或运算),最后再与数组长度-1 做按位与运算,效率较高
    
    6.解决hashcode冲突上的不同
         hashtable使用的是Entry节点来保证冲突的
         hashmap是使用链表|红黑树来保证hashcode冲突的
7.遍历方式的不同 Hashtable、HashMap都使用了Iterator。而由于历史原因,Hashtable还使用了Enumeration的方式
8.contains方法上的不同 hashtable有contains,containsValue和containsKey三个方法 hashMap把contains方法去掉了,只保留了containsKey和containsValue方法

 

posted @ 2020-04-04 13:53  硝烟漫过十八岁  阅读(205)  评论(0编辑  收藏  举报