HashTable 和 HashMap 区别

117 阅读3分钟

「这是我参与2022首次更文挑战的第13天,活动详情查看:2022首次更文挑战

在面试中,这道题其实属于一个比较基础的面试题了,当我们在学习 Java SE 基础的时候,大家应该学过一些集合框架,这两个类都是 Map 这个接口下面的两个比较重要的实现子类。

面试中经常会被问到它们两个之间的一个区别,区别点还是挺多的。来看一下这两个类有什么区别。

HashTable 是线程同步的,HashMap 是非线程同步的。这个线程同步和非线程同步代表什么意思呢?其实代表的是安全性。因为我们在后续操作过程中,或者说在我们实际的一个业务逻辑处理过程中,经常会有多线程一些并发操作,在并发操作的时候如何保证线上安全呢?这里面给了两个类,如果你用 HashTable的话,它的数据是不会乱的,不管你有多少个线程处理都没有问题。而如果你用 HashMap 的话,多线程处理的时候可能会引发一系列的问题。这个两个类关键点在什么地方?如果你看过这两个类的关键核心源码的话,应该能知道,在 HashTable 这个类的很多方法上面会加一个关键字,即 synchronized 关键字。synchronized 本身就表示线程同步的意思,它方法上面都会加 synchronized 这样一个操作,表示我的方法是安全的。而 HashMap 面的方法就没有 synchronized 关键。其实 sync hronized 这个关键字最核心的点在哪儿,在于效率方面。如果你用 HashTable 的话,虽然它是线上同步的,是线上安全的,但是同时也意味着它的效率是比较低的。而如果你用 HashMap 的话,它的方法没有使用 synchronized 这关键字,它的线数据虽然不安全,但是效率是比较高的。因此在实际的工作场景里面,你要做一个合理的选择。

HashTable 不允许键值有空值,HashMap 允许键值有空值,什么意思,当我们再往这些 Map 结构里面存储具体数据的时候, Key-Value,如你想有空值,必须只能用 HashMap。而在 HashMap 里面也只允许 Key 有一个空值,Value 可以有多个空值。而用 HashTable 的话,不好意思,你的 Key 也好,还是你的 Value 也好,它全部都不允许有空值。

HashTable 使用 Enumeration,HashMap 使用 Iterator。这里需要注意,在现在版本里面 HashMap 也好,HashTable 也好,它都支持了 Iterator。但是由于一些历史原因,HashTable 含支持。而我们在日常工作中使用更多的其实还是 Iterator。

HashTable 中 hash 数组默认大小是 11,增长的方式是 odlx2+1,也就是每次我们在进行往里面放数据的时候,如果你的容量不够了,我是需要进行扩容的。他们扩容之后你的数量级是不同的。HashTable 是原来大小的 2 倍,并且加上 1,HashMap 中 Hash 数组的默认大小是 16,增长方式 2 的指数陪。这个算法导论这本书里面会有这样一个提示,说如果你要使用 Hash 取模这样方式的话,推荐大家把这个基础的数据值设置成基数。为什么 HashMap 还是用了 16 这样一个偶数呢?它是为了方便我们后面在进行未运算的时候和我们进行数据迁移的时候,为了方便进行计算而已。

HashTable继承 Dictionary 类,而 HashMap 继承 AbstractMap 类。它们两个的父类是不同的,它们同同时都实现了 Map 接口。