HashMap 与 HashTable 的区别
HashMap 与 HashTable 的区别
1. 数据结构方面
HashTable 使用的是数组 + 链表
HashMap 1.7 之前与HashTable 一致, 1.7 之后引入红黑树
2. 初始容量和扩容
HashTable 初始容量是11 扩容 2n+1
HashMap 初始容量16 扩容2n
3. 是否允许null作为key
HashMap 允许, HashTable 不允许
4. 线程安全
HashTable 为线程安全,因为HashTable 在put (大多数)方法前加入了synchronized
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();
int index = (hash & 0x7FFFFFFF) % tab.length;
@SuppressWarnings("unchecked")
Entry<K,V> entry = (Entry<K,V>)tab[index];
for(; entry != null ; entry = entry.next) {
if ((entry.hash == hash) && entry.key.equals(key)) {
V old = entry.value;
entry.value = value;
return old;
}
}
addEntry(hash, key, value, index);
return null;
}
为什么HashTable 不允许null值作为key
HashMap 源码
static final int hash(Object key) {
int h;
return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
}
HashTable 源码
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();
作者思考
This class implements a hash table, which maps keys to values. Any
* non-nullobject can be used as a key or as a value.
*
* To successfully store and retrieve objects from a hashtable, the
* objects used as keys must implement thehashCode
* method and theequalsmethod.
Hashtable 设计较早,不允许 null
Hashtable是 JDK 1.0 时代的类,最早的设计时考虑的是严格的安全性,因此put(key, value)里key和value都不允许为null,以防止NullPointerException。- 代码中,它的
put方法直接调用Objects.requireNonNull(key),不允许null。
HashMap 设计更灵活,允许 null
HashMap是 JDK 1.2 才引入的,设计上更灵活,允许null作为 key 和 value。HashMap允许nullkey,是因为nullkey 在很多场景下是有意义的,比如:map.get(null)可以作为一种默认值的查找机制。- 在 JSON、数据库等数据格式中,
null也是合法的 key。
HashMap内部对nullkey 进行特殊处理:nullkey 总是存储在数组的 第一个 bucket 里,而非通过hashCode()计算索引
2. 为什么 HashMap 和 Hashtable 的设计不同?
(1) 线程安全性
Hashtable是同步的(synchronized),防止null作为 key 或 value 能减少NullPointerException,避免不必要的synchronized代码块出现问题。HashMap不是线程安全的,所以允许null更符合非同步环境的需求。
(2) 设计原则
HashMap设计时追求 性能和灵活性,避免null反而会降低使用的灵活性。Hashtable作为老 API,设计上偏向 严格的约束,更符合早期 Java 的安全性要求。

浙公网安备 33010602011771号