面试题:HashMap和Hashtable的区别和联系

摘要:从源码、特性和算法实现等几个角度归纳HashMap和Hashtable的区别和联系。

  HashMap与Hashtable的区别是面试中经常遇到的一个问题。此问题看似简单,但如若深挖,也可以学习到很多底层知识。本文对两者从源码、特性和算法实现等几个角度进行归纳总结,力争多角度、全方位的立体式展示二者的区别和联系,帮助各位应聘者在面试时飙车不飘车,把面试官摁在地上摩擦。

  相同点

  • 都是以key-value键值对的形式存储数据;
  • 都实现了Serializable接口,故支持序列化;
  • 都实现了Cloneable接口,故能被克隆;
  • 都实现了Map接口。

  各自实现的接口如下图所示:

HashMap

Hashtable

  不同点比较多,归纳为以下几点:

  对Null key 和Null value的支持不同。HashMap允许Key-value为null,Hashtable不允许;

  hash值算法不同。HashMap添加元素时,是使用自定义的哈希算法,而Hashtable直接采用key的hashCode();

  底层数据结构不同。HashMap 自jdk8开始,底层数据结构采用数组+链表+红黑树,而Hashtable采用数组+链表;

  线程安全性不一样。HashMap没有考虑同步,是线程不安全的。Hashtable是线程安全的,给api套上了一层synchronized修饰;

  虽然HashMap不是线程安全的,但是它的效率会好于Hashtable。这样别出心裁的设计是合理的,在日常应用中,大部分场景是单线程操作的。HashMap把这部分操作解放出来了。

  初始容量和扩容方式不一样。HashMap默认的初试容量大小是16;扩容时,每次将容量变为“原始容量x2”。Hashtable默认的容量大小是11;扩容时,每次将容量变为“原始容量x2 + 1”;

  另外,无论我们指定的容量为多少,构造方法都会将HashMap实际容量设为不小于指定容量的2的次方的一个数,且最大容量不能超过2的30次方。

  继承的父类不同。HashMap继承于AbstractMap类,Hashtable继承自Dictionary类;不过,Dictionary类是一个已经被废弃的类,父类都被废弃,自然而然也没人用它的子类Hashtable了。

  对外提供的接口不同。Hashtable比HashMap多提供了elments() 和contains() 两个方法。

  迭代器(Iterator)不同。HashMap的迭代器(Iterator)是fail-fast迭代器,而Hashtable的enumerator迭代器不是fail-fast的。所以当有其它线程改变了HashMap的结构(增加或者移除元素),将会抛出ConcurrentModificationException。

posted @ 2021-06-23 11:30  楼兰胡杨  阅读(307)  评论(0编辑  收藏  举报