HashMap和Hashtable的区别?
HashMap和Hashtable都是Map接口的实现类,Hashtable继承自Dictionary类,而HashMap继承自AbstractMap类,底层实现都是链表+数组
HashMap和Hashtable主要有一下几点
- 父类不同
- 初始容量不同
- 是否是线程安全
- 对null值的支持
父类不同
查看继承类结构图快捷键:ctrl+alt+shift+u
-
HashMap结构图如下
-
Hashtable结构图如下
初始容量不同
HashMap初始容量为16,Hashtable初始容量为11,增长因子倒是一致。
// HashMap初始化代码
/**
* The load factor used when none specified in constructor.
*/
static final float DEFAULT_LOAD_FACTOR = 0.75f;
public HashMap() {
this.loadFactor = DEFAULT_LOAD_FACTOR; // all other fields defaulted
}
// Hashtable初始化代码
public Hashtable() {
this(11, 0.75f);
}
是否是线程安全
HashMap和Hashtable前者是线程不安全的,后者是线程安全的
Hashtable保证线程安全的方式比较简单都是,直接使用synchronized。我们可以看看一下这些常用操作,都有在方法上使用synchronized来修饰。
public synchronized V put(K key, V value) {
…
}
public synchronized V get(Object key) {
…
}
public synchronized V remove(Object key) {
…
}
public synchronized boolean contains(Object value) {
…
}
对null值的支持
HashMap可以有一个null key,并且可以有的多个null value, Hashtable不允许有null key同时也不知道null value
在Hashtable当中,我们可以看到put操作的时候,如果value等于null,源码当中直接就做了throw new NullPointerException
public synchronized V put(K key, V value) {
// Make sure the value is not null
if (value == null) {
throw new NullPointerException();
}
// Makes sure the key is not already in the hashtable.
Entry<?,?> tab[] = table;
int hash = key.hashCode();
…
}
如果key等于null key.hashCode();就直接throw new NullPointerException, value为null有相应判断。
拓展[数据插入效率对比] 单线程执行
数据类型 + 操作 | 时间 |
---|---|
HashMap put 1w | 654ms |
HashMap put 10w | 968ms |
HashMap put 100w | 4040ms |
Hashtable put 1w | 42ms |
Hashtable put 10w | 312ms |
Hashtable put 100w | 3625ms |
单线程的情况下HashMap的执行效率确实要比Hashtable要低一些,但是如果是多线程环境Hashtable的执行效率肯定是会比HashMap低的