AI大模型教程
一起来学习

【1.JDK底层源码剖析】2.3HashMap初始容量及扩容机制

Hashtable 与 HashMap 的区别(结合 Java 底层源码分析)


1. 线程安全性
  • Hashtable
    所有公开方法通过 synchronized 实现线程安全:

    // Hashtable 源码片段 (JDK 1.8)
    public synchronized V put(K key, V value) { ... }
    public synchronized V get(Object key) { ... }
    

    每次操作锁住整个表,高并发下性能差

  • HashMap
    非线程安全,无同步机制:

    // HashMap 源码片段 (JDK 1.8)
    public V put(K key, V value) { ... } // 无 synchronized
    

    需手动同步(如 Collections.synchronizedMap)或使用 ConcurrentHashMap


2. Null 键值处理
  • Hashtable
    不允许 null 键或值,否则抛 NullPointerException

    public synchronized V put(K key, V value) {
        if (value == null) throw new NullPointerException(); // 值检查
        int hash = key.hashCode(); // 若 key=null 此处抛 NPE
        ...
    }
    
  • HashMap
    允许一个 null 键和多个 null 值,特殊处理 null 键:

    static final int hash(Object key) {
        int h;
        return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16); // 处理 null
    }
    

3. 哈希算法与冲突解决
  • 初始容量与扩容

    • Hashtable
      默认容量 11,扩容公式:新容量 = 旧容量 * 2 + 1

      int newCapacity = (oldCapacity  1) + 1; // 位运算优化
      
    • HashMap
      默认容量 16(2 的幂),扩容公式:新容量 = 旧容量 * 2

      newCap = oldCap  1; // 保证容量始终为 2^n
      
  • 哈希计算

    • Hashtable 直接使用对象的 hashCode()

      int hash = key.hashCode();
      int index = (hash & 0x7FFFFFFF) % table.length; // 取模运算
      
    • HashMap 优化哈希分布(扰动函数):

      static final int hash(Object key) {
          int h;
          return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16); // 高位异或
      }
      // 计算索引: (n-1) & hash
      
  • 冲突解决
    两者均使用 链表法,但 HashMap 在 Java 8 引入红黑树优化

    // HashMap 链表转树阈值 (TREEIFY_THRESHOLD = 8)
    if (binCount >= TREEIFY_THRESHOLD - 1)
        treeifyBin(tab, hash);
    

4. 迭代器设计
  • Hashtable
    使用 Enumeration 遍历,不支持快速失败(Fail-Fast)机制:

    public EnumerationK> keys() {
        return getEnumeration(KEYS);
    }
    
  • HashMap
    使用 Iterator 并支持 Fail-Fast

    final class KeyIterator extends HashIterator implements IteratorK> {
        public final K next() { return nextNode().key; }
    }
    

    迭代时检测 modCount,若结构被修改则抛 ConcurrentModificationException


5. 继承体系
  • Hashtable
    继承陈旧的 Dictionary 类:

    public class HashtableK,V> extends DictionaryK,V> ... 
    
  • HashMap
    继承现代的 AbstractMap 类:

    public class HashMapK,V> extends AbstractMapK,V> ...
    

总结对比表

特性 Hashtable HashMap
线程安全 是(同步方法) 否(需外部同步)
Null 键值 禁止 允许一个 null 键和多个 null 值
初始容量 11 16(2^n)
扩容机制 旧容量*2 + 1 旧容量*2
哈希计算 直接取模 hash % length (n-1) & hash(位运算优化)
冲突解决 链表 链表 + 红黑树(JDK8+)
迭代器 Enumeration(非快速失败) Iterator(支持 Fail-Fast)
继承类 Dictionary AbstractMap
性能 低(同步开销)

使用建议

  1. 单线程环境:优先使用 HashMap(更高性能)。
  2. 高并发场景:用 ConcurrentHashMap 替代 Hashtable(分段锁优化)。
  3. 遗留系统兼容:需线程安全且不介意性能时再用 Hashtable

文章来源于互联网:【1.JDK底层源码剖析】2.3HashMap初始容量及扩容机制

相关推荐: 【AI】入门级提示词模板:适用于ChatGPT、文心一言等主流模型

  入门级提示词模板:适用于 ChatGPT、文心一言等主流模型 ** 在当下这个人工智能飞速发展的时代,ChatGPT、文心一言等主流大模型已经广泛地融入到我们的工作与生活当中。不管是创作文章、生成代码,还是进行数据分析、获取创意灵感,这些大模型都能展现出令…

赞(0)
未经允许不得转载:5bei.cn大模型教程网 » 【1.JDK底层源码剖析】2.3HashMap初始容量及扩容机制
分享到: 更多 (0)

AI大模型,我们的未来

小欢软考联系我们