HashMap和HashTable有什么不同?在面试和被面试的过程中,我问过也被问过这个问题,也见过了不少回答,今天决定写一写自己心目中的理想答案。
代码版本
JDK每一版本都在改进。本文讨论的HashMap和HashTable基于JDK 1.7.0_67。源码见这里
1. 时间
HashTable产生于JDK 1.1,而HashMap产生于JDK 1.2。从时间的维度上来看,HashMap要比HashTable出现得晚一些。
2. 作者
以下是HashTable的作者:
1
2
3
4
5
|
以下代码及注释来自java.util.HashTable
*
@author
Arthur van Hoff
*
@author
Josh Bloch
*
@author
Neal Gafter
|
以下是HashMap的作者:
1
2
3
4
5
6
|
以下代码及注释来自java.util.HashMap
*
@author
Doug Lea
*
@author
Josh Bloch
*
@author
Arthur van Hoff
*
@author
Neal Gafter
|
可以看到HashMap的作者多了大神Doug Lea。不了解Doug Lea的,可以看这里。
3. 对外的接口(API)
HashMap和HashTable都是基于哈希表来实现键值映射的工具类。讨论他们的不同,我们首先来看一下他们暴露在外的API有什么不同。
3.1 Public Method
下面两张图,我画出了HashMap和HashTable的类继承体系,并列出了这两个类的可供外部调用的公开方法。
从图中可以看出,两个类的继承体系有些不同。虽然都实现了Map、Cloneable、Serializable三个接口。但是HashMap继承自抽象类AbstractMap,而HashTable继承自抽象类Dictionary。其中Dictionary类是一个已经被废弃的类,这一点我们可以从它代码的注释中看到:
1
2
3
4
|
以下代码及注释来自java.util.Dictionary
* <strong>NOTE: This
class
is obsolete. New implementations should
* implement the Map
interface
, rather than extending
this
class
.</strong>
|
同时我们看到HashTable比HashMap多了两个公开方法。一个是elements,这来自于抽象类Dictionary,鉴于该类已经废弃,所以这个方法也就没什么用处了。另一个多出来的方法是contains,这个多出来的方法也没什么用,因为它跟containsValue方法功能是一样的。代码为证:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
以下代码及注释来自java.util.HashTable
public
synchronized
boolean
contains(Object value) {
if
(value ==
null
) {
throw
new
NullPointerException();
}
Entry tab[] = table;
for
(
int
i = tab.length ; i-- >
0
;) {
for
(Entry<K,V> e = tab[i] ; e !=
null
; e = e.next) {
if
(e.value.equals(value)) {
return
true
;
}
}
}
return
false
;
}
public
boolean
containsValue(Object value) {
return
contains(value);
}
|
所以从公开的方法上来看,这两个类提供的,是一样的功能。都提供键值映射的服务,可以增、删、查、改键值对,可以对建、值、键值对提供遍历视图。支持浅拷贝,支持序列化