Java中的HashMap和HashTable到底哪不同?
小明 Lv6

父类不同

  • HashMap 继承自 AbstractMap;
  • Hashtable 继承自 Dictionary;

线程安全性不同

  • HashMap 线程不安全;
    Hashtable 线程安全,因为 打开Hashtable的源码可以看到,很多方法都是同步的(synchronized)。

    注意:同步的代价就是性能损失,非线程安全场景,建议使用 HashMap。
    虽然Hashtable是线程安全的,但仍然不建议在多线程环境下使用Hashtable。因为它是一个古老的API,从Java 1.0开始就出现了,它的同步方案还不成熟,性能不好。

如果要在多线程环下使用HashMap,建议使用ConcurrentHashMap。它不但保证了线程安全,也通过降低锁的粒度提高了并发访问时的性能。

key、value 是否允许null?

  • HashMap 的 key 和 value 都可以为 null,key 只允许一个 null;
  • Hashtable 的 key 和 value 都不能为 null;

迭代器不同

  • HashMap.entrySet() 的 Iterator 是 fail-fast 迭代器;
  • Hashtable.elements() 使用 的是Enumerator 迭代器;

什么是 fail-fast?

fail-fast 机制是 java 集合中的一种错误机制。当多个线程对同一个集合的内容进行操作时,就可能会产生 fail-fast 事件。例如:当某一个线程 A 通过 iterator 去遍历某集合的过程中,若该集合的内容被其他线程所改变了;那么线程A访问集合时,就会抛出
ConcurrentModificationException 异常,产生 fail-fast 事件。

hash 的计算方式不同

  • HashMap 计算了 hash 值;HashMap 中最核心的部分就是哈希函数,又称散列函数。也就是说,哈希函数是通过把 key 的 hash 值映射到数组中的一个位置来进行访问。
  • Hashtable 使用了 key 的 hashCode 方法;

默认初始大小和扩容方式不同

**HashMap 默认初始大小 16,容量必须是 2 的整数次幂,扩容时将容量变为原来的2倍;

  • Hashtable 默认初始大小 11,扩容时将容量变为原来的 2 倍加 1;

是否有 contains 方法?

  • HashMap 没有 contains 方法,但是添加了 containsValue() 和 containsKey() 方法;
  • Hashtable 包含 contains 方法,类似于 containsValue;

关注获取更多资源

image
 评论