HashMap和HashTable的区别

1.父类和实现接口不同

HashMap:父类AbstractMap,实现接口Cloneable,Serializable,map

HashTable:父类Dictionary, 实现接口Cloneable,Serializable,map

2.相关方法

HashTable比HashMap多了两个方法,elments(),contain()

  1. elments() 方法继承自Hashtable的父类Dictionnary。elements() 方法用于返回此Hashtable中的value的枚举。
  2. contains()方法判断该Hashtable是否包含传入的value。它的作用与containsValue()一致。事实上,contansValue() 就只是调用了一下contains() 方法。

 

3.对Null key 和Null value的支持不同

  1. HashTable不支持nullKey和nullvalue,

                 当null key时,调用put方法,运行到一步就会出现空指针异常。

                 当null value时,hashtable也做了限制,报空指针异常。

                If(value==null) {

                     Throw new NullpointerException();

                }

            2.HashMapkey为null的键只有一个,而value为null的键可以有多个。

                当get()方法返回null值时,可能时HashMap中没有该键,也可能时改键值为null。

                因此,在HashMap中不能由get()方法来判断HashMap中是否存在某个键,而应该用containsKey()方法来判断。

4.线程安全方面

  1. Hashtable是线程安全的,它的每个方法中都加入了Synchronize方法。在多线程并发的环境下,可以直接使用Hashtable,不需要自己为它的方法实现同步。
  2. HashMap不是线程安全的,在多线程并发的环境下,可能会产生死锁等问题。

5.效率

  1. HashMap不是线程安全的,但是它的效率要比HashTable好很多。HashMap大多用于单线程操作。
  2. 当需要多线程操作时,可以使用线程安全的ConcurrentHashMap.ConcurrentHashMap是线程安全的,它的效率比HashTable要快好几倍。因为ConcurrentHashMap使用了分段锁,并不对整个数据进行*。

6.遍历方式的内部实现上不同

  1. Hashtable、HashMap都使用了 Iterator。而由于历史原因,Hashtable还使用了Enumeration的方式
  2. HashMap的Iterator是fail-fast迭代器。
  3. JDK8之前的版本中,Hashtable是没有fast-fail机制的。在JDK8及以后的版本中 ,HashTable也是使用fast-fail的

7.初始容量大小和每次扩充容量大小的不同

  1. HashTable默认的初始大小为11,之后每次扩充,容量变为原来的2n+1。
  2. HashMap默认的初始化大小为16。之后每次扩充,容量变为原来的2倍。

8.计算hash值的方法不同

Hashtable直接使用对象的hashCode。hashCode是JDK根据对象的地址或者字符串或者数字算出来的int类型的数值。然后再使用除留余数发来获得最终的位置。

  1. HashTable在计算元素的位置时需要进行一次除法运算,而除法运算是比较耗时的。
  2. HashMap为了提高计算效率,将哈希表的大小固定为了2的幂,这样在取模预算时,不需要做除法,只需要做位运算。位运算比除法的效率要高很多。

              HashMap的效率虽然提高了,但是hash冲突却也增加了。因为它得出的hash值的低位相同的概率比较高,而计算位运算。

             为了解决这个问题,HashMap重新根据hashcode计算hash值后,又对hash值做了一些运算来打散数据。使得取得的位置更加分散,从而减少了hash冲突。

 

 

 

 

 

 

 

 

 

 

 

 

上一篇:周末去面试,进去 5 分钟就出来了…


下一篇:HashMap and a Hashtable in Java 有什么区别?| Java Debug 笔记