HashMap和HashTable的区别

HashMap和HashTable异同

HashMap和Hashtable都实现了Map接口,但决定用哪一个之前先要弄清楚它们之间的分别。
主要的区别有:

  1. 线程安全性–同步(synchronization)
  2. 键值是否允许为null
  3. 类继承
  4. 初始化及扩容
  5. 迭代器以及速度

线程安全

HashMap是非synchronized,而Hashtable是synchronized。Hashtable 所有的元素操作都是 synchronized 修饰的,而 HashMap 并没有。

这意味着Hashtable是线程安全的,多个线程可以共享一个Hashtable。而如果没有正确的同步的话,多个线程是不能共享HashMap的。Java 5提供了ConcurrentHashMap,它是HashTable的替代,比HashTable的扩展性更好。

HashTable只能由一个线程操作, ConcurrentHashMap可以让一个线程操作第一个Segment,另一个线程操作另一个Segment
``

NULL

Hashtable 是不允许键或值为 null 的,HashMap 的键值则都可以为 null(只有一个键允许为null)。

HashMap几乎可以等价于Hashtable,除了HashMap是非synchronized的,并可以接受null(HashMap可以接受为null的键(key)和值(value),而Hashtable则不行)。

为什么 Hashtable 是不允许 KEY 和 VALUE 为 null, 而 HashMap 则可以?

Hashtable中如果key/ value 为 null 会直接抛出空指针异常,而 HashMap 的逻辑对 null 作了特殊处理。

类继承

Hashtable如下:

public class Hashtable<K,V>
    extends Dictionary<K,V>
    implements Map<K,V>, Cloneable, java.io.Serializable {}

HashMap如下:

public class HashMap<K,V> extends AbstractMap<K,V>
    implements Map<K,V>, Cloneable, Serializable {}

可以看出两者继承的类不一样,Hashtable 继承了 Dictionary类,而 HashMap 继承的是 AbstractMap 类。

Dictionary 是 JDK 1.0 添加的,很古老的一个字典类。其javadoc如下所示:

Dictionary是键值对映射类的抽象父类,例如Hashtable。
每一个键和值都是一个object。每个键最多关联一个值。
给定一个Dictionary对象和一个键,关联的元素可以被找到。
任何非 null 对象都可以用作键和值。
通常,这个类的实现应该使用equals方法来确定两个键是否相同
注意:这个类已经过时。新的实现应该实现Map接口,而不是继承这个类

初始化和容量扩容

HashMap 的初始容量为:16,Hashtable 初始容量为:11,两者的负载因子默认都是:0.75。

当现有容量大于总容量 * 负载因子时,HashMap 扩容规则为当前容量翻倍,Hashtable 扩容规则为当前容量翻倍 + 1。

迭代器

另一个区别是HashMap的迭代器(Iterator)是fail-fast迭代器,而Hashtable的Enumerator迭代器不是fail-fast的。

所以当有其它线程改变了HashMap的结构(增加或者移除元素),将会抛出ConcurrentModificationException,但迭代器本身的remove()方法移除元素则不会抛出ConcurrentModificationException异常。

但这并不是一个一定发生的行为,要看JVM的实现。这同样也是Enumeration和Iterator的区别。

速度与性能

由于Hashtable是线程安全的也是synchronized,所以通常它比HashMap要慢。如果你不需要同步,只需要单一线程,那么使用HashMap性能要好过Hashtable。

如果要线程安全又要保证性能,建议使用 JUC 包下的 ConcurrentHashMap。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值