Java 中的 HashMap 和 Hashtable 有什么区别?
虽然 Hashtable 和 HashMap 都是基于哈希和Map接口实现的数据结构,但它们之间的主要区别在于 HashMap 不是线程安全的,而 Hashtable 是线程安全的。 这意味着我们不能在没有外部同步的情况下在多线程 Java 应用程序中使用 HashMap。 另一个区别是 HashMap 允许一个空键和一个空值,而 Hashtable 不允许一个空键或空值。 此外,哈希表的线程安全是使用内部同步实现的,这使得它比 HashMap 慢。
顺便说一句,Java 中的 HashMap 和 Hashtable 之间的区别是核心 Java 面试中经常被问及的问题之一,以检查候选人是否理解集合类的正确用法并了解可用的替代解决方案。
除了 HashMap 在 Java 中的内部工作方式和 ArrayList vs Vector 之外,这是 Java 集合框架中最古老的问题之一。 Hashtable 是一个遗留的 Collection
类,它在 Java API 中存在了很长时间,但它在 Java 4 中被重构以实现 Map 接口,从那里 Hashtable 成为 Java Collection 框架的一部分。
Java 中的 Hashtable vs HashMap 是一个非常受欢迎的问题,它可以排在任何 Java 集合面试问题列表的首位。在这篇 Java 文章中,我们不仅会看到 HashMap 和 Hashtable 之间的一些重要区别,还会看到这两个集合类之间的一些相似之处。 虽然准备充分,
让我们先看看它们有何不同:
Java中 HashMap 和 Hashtable 的区别
HashMap 和 Hashtable 都实现了 Map 接口,但它们之间存在一些显着差异,在决定在 Java 中使用 HashMap 还是 Hashtable 之前,需要记住这一点很重要。 其中一些是线程安全、同步和速度。 这是这些差异:
1. HashMap 类大致等同于 Hashtable,只是它是非同步的,并且允许null。 (HashMap 允许空值作为键和值,而 Hashtable 不允许空值)。
2. HashMap 和 Hashtable 的主要区别之一是 HashMap 是非同步的,而 Hashtable 是同步的,这意味着 Hashtable 是线程安全的,可以在多个线程之间共享,但 HashMap 不能在没有适当同步的情况下在多个线程之间共享。 Java 5 引入了 ConcurrentHashMap
,它是 Hashtable 的替代品,提供比 Java 中的 Hashtable 更好的可扩展性。
3. HashMap 与 Hashtable 之间的另一个显着区别是 HashMap 中的 Iterator
是一个快速失败的迭代器,而 Hashtable 的枚举器不是,如果任何其他线程通过添加或删除除 Iterator
自己的 remove
之外的任何元素在结构上修改映射,则抛出 ConcurrentModificationException()
方法。 但这不是保证的行为,将由 JVM 尽最大努力完成。 这也是Java中 Enumeration 和 Iterator 的一个重要区别。
4. Hashtable 和 HashMap 之间的一个更显着的区别是,由于线程安全和同步,如果在单线程环境中使用,Hashtable 比 HashMap 慢得多。 所以如果你不需要同步,HashMap 只被一个线程使用,它的性能优于 Java 中的 Hashtable。
5. HashMap 不保证映射的顺序会随着时间的推移保持不变。
HashMap 和 Hashtable:一些重要术语的注意事项
1)同步意味着在一个时间点只有一个线程可以修改哈希表。 基本上,这意味着任何线程在对 Hashtable 执行更新之前都必须获取该对象的锁,而其他线程将等待锁被释放。
2)故障安全与迭代器的上下文相关。 如果在集合对象上创建了 Iterator 或 ListIterator,并且其他某个线程试图“结构化”修改集合对象,则会抛出并发修改异常。 其他线程可以调用 set
方法,因为它不会“结构性”修改集合。 但是,如果在调用 set
之前,集合已在结构上进行了修改,则会抛出 IllegalArgumentException
。
- 结构修改是指删除或插入能有效改变 Map 结构的元素。
HashMap 可以通过同步
Map m = Collections.synchronizeMap(hashMap);
总之,Hashtable 和 HashMap 在Java中存在着显著的差异,例如线程安全性和速度,基于这一点,只有在我们运行Java 5时绝对需要线程安全性时才使用 Hashtable。否则考虑在Java中使用 ConcurrentHashMap
。
相关文章
在 Java 中获取文件大小
发布时间:2023/05/01 浏览次数:139 分类:Java
-
Java 提供了不同的方法来获取文件的字节大小。 本教程演示了在 Java 中获取文件大小的不同方法。使用 Java IO 的文件类获取文件大小 Java IO 包的 File 类提供了以字节为单位获取文件大小的功能。
Java 中的文件分隔符
发布时间:2023/05/01 浏览次数:108 分类:Java
-
本篇文章介绍了 Java 中的文件分隔符。Java 中的文件分隔符 文件分隔符是用来分隔目录的字符; 例如,Unix 使用 /,Windows 使用 \ 作为文件分隔符。
Java 中的文件过滤器
发布时间:2023/05/01 浏览次数:193 分类:Java
-
本篇文章介绍如何在 Java 中使用 FileFilter。FileFilter 用于过滤具有特定扩展名的文件。 Java内置包IO和Apache Commons IO为FileFilter提供了类和接口来进行文件过滤操作。
Java 获取 ISO 8601 格式的当前时间戳
发布时间:2023/05/01 浏览次数:132 分类:Java
-
本篇文章介绍了 ISO 8601 日期格式、其重要性及其在 Java 中的使用。 它还列出了一些优点来强调为什么应该使用 ISO 格式来表示日期。
在 Java 中获取数组的子集
发布时间:2023/05/01 浏览次数:142 分类:Java
-
本篇文章介绍了几种在 Java 中获取数组子集的方法。使用 Arrays.copyOf() 方法获取数组的子集 使用 Arrays.copyOfRange() 方法获取数组的子集
用 Java 填充二维数组
发布时间:2023/05/01 浏览次数:110 分类:Java
-
二维数组是基于表结构的,即行和列,填充二维数组不能通过简单的添加到数组操作来完成。 本篇文章介绍如何在 Java 中填充二维数组。
计算 Java 数组中的重复元素
发布时间:2023/05/01 浏览次数:202 分类:Java
-
本篇文章介绍Java计算数组中重复元素的方法。计算 Java 数组中的重复元素。我们可以创建一个程序来计算数组中的重复元素。 该数组可以是未排序的,也可以是已排序的。
Java 中 List 和 Arraylist 的区别
发布时间:2023/05/01 浏览次数:90 分类:Java
-
表示为单个单元的一组单个对象称为集合。 在 Java 中,Collection 是一个具有多个已定义接口和类的框架,用于将一组对象表示为一个单元。 它允许我们操纵