Hashtable 与 HashMap初探

缘由

听到前面now直播的大哥在面试同学,问了对面同学一个问题:请问Hashtable是用什么实现的?然后我就一脸愣逼,我记得《stl源码剖析》中好像没有讲到Hashtable,只说了mapsetmutimapmutiset,所以哈希是什么东西?黑人问号。我能说出set就是map的阉割版本,底层结构是红黑树,红黑树的定义,旋转以及为何要用红黑树,但是Hashtable确实不甚了解啊。唯一知道的就是经常拿它去和HashMap比较,什么线程安全啦,key,value都不能为null什么的。所以我就开始阅读源码,看看有什么区别?


实现的区别

Hashtable继承Dictionary类,可序列化,可以拷贝(实现了SerializableCloneable);与之相对HashMap多实现了Map和改为继承AbstractMap了。

Hashtable将元素存储在一个Entry[]数组,HashMap将元素存储在一个Node[]中。注意EntryNode都有一个关键属性next,为了以后hashcode冲突后进行头部插入元素用的。所以这两者都采用了链表的方法来解决冲突问题。

对于put方法,两者的最大区别在于hashcode的区别。Hashtable直接使用对象类定义的hashcode方法;而HashMap则是用了自定义hashcode,区别就是如下代码:

private int hashcode(Object o){
  return o -- null? 0 : o.hashcoe();
}

从设计模式的角度看,就是加了一个中间间,一个桥接方法,导致了即使key或者valuenull的时候也可以哈希,而不是跑出一个NPE

对于forEach方法。两者都差不多:两层for循环,第一层便利slot(槽区),第二个遍历单链。

对于get方法:HashMap多了一步——检查空值,而且HashMap中一般对于Node读取都要考虑null(比如containremove)。

至于为什么Hashtable是线程安全的,是因为它的方法加上了synchronic,所以线程安全。

还有就是HashMap内涵entrySet;冲突时链表添加节点的方法不一样,Hashtable是调用一个函数addEntry,而HashMap是用p.next = new Node(key, value)的。

总而言之,它们的区别就在于synchronichashcode,以及内部维护的数据规模不一样。

你可能感兴趣的:(Hashtable 与 HashMap初探)