HashMap 和 Hashtable 有什么区别?

2 个回答

  • 贝贝
    垆边人似月,皓腕凝霜雪。
    ### HashMap 和 Hashtable 的区别 #### 1. 父类不同 - **HashMap**:继承自 `AbstractMap` 类。 - **Hashtable**:继承自 `Dictionary` 类。 两者都实现了 `Map`、`Cloneable`(可复制)、`Serializable`(可序列化)这三个接口。 #### 2. 对外提供的接口不同 - **Hashtable**:比 `HashMap` 多提供了 `elements()` 和 `contains()` 两个方法。 - `elements()` 方法继承自 `Dictionary` 类,用于返回此 `Hashtable` 中的 `value` 的枚举。 - `contains()` 方法判断该 `Hashtable` 是否包含传入的 `value`,其作用与 `containsValue()` 一致。实际上,`containsValue()` 只是调用了 `contains()` 方法。 #### 3. 对 null 的支持不同 - **Hashtable**:`key` 和 `value` 都不能为 `null`。 - **HashMap**:`key` 可以为 `null`,但只能有一个这样的 `key`,因为必须保证 `key` 的唯一性;可以有多个 `key` 值对应的 `value` 为 `null`。 #### 4. 线程安全性不同 - **HashMap**:线程不安全,在多线程并发的环境下,可能会产生问题,如死锁等。需要开发人员自行处理多线程的安全问题。 - **Hashtable**:线程安全,每个方法上都有 `synchronized` 关键字,因此可以直接用于多线程环境中。 尽管 `HashMap` 是线程不安全的,但其效率远高于 `Hashtable`。这是因为大部分使用场景都是单线程的。当需要多线程操作时,可以使用线程安全的 `ConcurrentHashMap`。`ConcurrentHashMap` 的效率比 `Hashtable` 高很多,因为它使用了分段锁,并不对整个数据进行锁定。 #### 5. 初始容量和扩充容量大小不同 - **HashMap**:默认初始容量为 16,每次扩充容量为原来的两倍。 - **Hashtable**:默认初始容量为 11,每次扩充容量为原来的两倍加一。 #### 6. 计算 hash 值的方法不同 - **HashMap**:使用自身的 hash 算法,默认采用对象的 `hashCode` 值,并对其进行再加工(扰动函数),以减少冲突。 ```java static final int hash(Object key) { int h; return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16); } ``` - **Hashtable**:直接使用对象的 `hashCode` 值,计算方式较简单。 ```java int hash = key.hashCode(); ``` ### 总结 | 特性 | HashMap | Hashtable | |-----------------------------|---------------------------------------|--------------------------------| | **父类** | AbstractMap | Dictionary | | **额外方法** | 无 | `elements()`, `contains()` | | **对 null 的支持** | `key` 和 `value` 可以为 `null` | `key` 和 `value` 不能为 `null` | | **线程安全性** | 线程不安全 | 线程安全 | | **初始容量和扩充容量** | 初始容量 16,扩充容量为原来的两倍 | 初始容量 11,扩充容量为原来的两倍加一 | | **hash 值计算** | 使用自定义的 hash 算法 | 使用对象的 `hashCode` 值 | 选择使用哪种数据结构应根据具体的使用场景来决定。如果在多线程环境下,需要使用线程安全的集合,可以选择 `ConcurrentHashMap`,而不是 `Hashtable`。
    发布于 2024-05-27 23:25 •IP属地 北京
    举报
    评论
    收藏

  • 吴敏
    你爱你的玫瑰是因为你在你的玫瑰上花了太多的时间!
    hashMap去掉了HashTable 的contains方法,但是加上了containsValue()和containsKey()方法。 hashTable同步的,而HashMap是非同步的,效率上逼hashTable要高。 hashMap允许空键值,而hashTable不允许。
    发布于 2021-06-29 17:43 •IP属地 江西
    举报
    评论
    收藏