HashMap 与HashTable的区别

2023-10-31

HashMap 与HashTable的区别

HashMap与Hashtable的区别是面试中经常遇到的一个问题。这个问题看似简单,但如果深究进去,也能了解到不少知识。本文对两者从来源,特性,算法等多个方面进行对比总结。力争多角度,全方位的展示二者的不同,做到此问题的终结版。

1 作者
Hashtable的作者:
这里写图片描述
HashMap的作者:
这里写图片描述

Hash Map的作者比Hashtable的作者多了著名顶顶的并发大神Doug Lea。他写了util.concurrent包。著有并发编程圣经Concurrent Programming in Java: Design Principles and Patterns 一书。他的个人主页: http://g.oswego.edu/

Josh Bloch 为领导了众多Java平台特性的设计和实现,其中包括Java Collection框架、java.math包以及assert机制。著有 Effective Java 一书。

Arthur van Hoff最早任职于硅谷的Sun Microsystems公司,从事Java程序语言的早期开发工作。设计并实现了JDK 1.0的许多方面,包括Java编译器、Java调试器、许多标准Java类以及HotJava浏览器。随后创立了多家成功的企业,其中包括Marimba(1999年IPO)、Strangeberry(后被TiVo收购)、ZING(后被Dell收购)和Ellerdale(后被Flipboard收购)。Java命名来源有这么一种说法,来源于开发人员名字的组合:James Gosling、Arthur Van Hoff和Andy Bechtolsheim首字母的缩写。

Neal Gafter是Java SE 4和5语言增强的主要设计者和实现者,他的Java闭包实现赢得了OpenJDK创新者挑战赛的大奖。他也在继续参与SE 7和8的语言发展。之前Neal在为Google的在线日历工作,也曾经是C++标准委员会的一员,并曾在Sun微系统公司,MicroTec研究院和德州仪器领导开发C和C++编译器。如今Neal在微软开发.NET平台编程语言。Neal是《Java Puzzlers:Traps, Pitfalls and Corner Cases》(Addison Wesley,2005)一书的合作者。他拥有罗彻斯特大学计算机科学的博士学位。

可见这些作者都是java乃至整个it领域大名鼎鼎的人物。也只有这些大师级人物才能写出HashMap这么大道至简的数据类型了。

2 产生时间
Hashtable是java一开始发布时就提供的键值映射的数据结构,而HashMap产生于JDK1.2。虽然Hashtable比HashMap出现的早一些,但是现在Hashtable基本上已经被弃用了。而HashMap已经成为应用最为广泛的一种数据类型了。造成这样的原因一方面是因为Hashtable是线程安全的,效率比较低。另一方面可能是因为Hashtable没有遵循驼峰命名法吧。。。

3 继承的父类不同
HashMap和Hashtable不仅作者不同,而且连父类也是不一样的。HashMap是继承自AbstractMap类,而HashTable是继承自Dictionary类。不过它们都实现了同时实现了map、Cloneable(可复制)、Serializable(可序列化)这三个接口

这里写图片描述

这里写图片描述

Dictionary类是一个已经被废弃的类(见其源码中的注释)。父类都被废弃,自然而然也没人用它的子类Hashtable了。

  • NOTE: This class is obsolete. New implementations should
  • implement the Map interface, rather than extending this class.

4 对外提供的接口不同
Hashtable比HashMap多提供了elments() 和contains() 两个方法。

elments() 方法继承自Hashtable的父类Dictionnary。elements() 方法用于返回此Hashtable中的value的枚举。

contains()方法判断该Hashtable是否包含传入的value。它的作用与containsValue()一致。事实上,contansValue() 就只是调用了一下contains() 方法。

这里写图片描述

5 对Null key 和Null value的支持不同
Hashtable既不支持Null key也不支持Null value。Hashtable的put()方法的注释中有说明。
这里写图片描述

当key为Null时,调用put() 方法,运行到下面这一步就会抛出空指针异常。因为拿一个Null值去调用方法了。
这里写图片描述

当value为null值时,Hashtable对其做了限制,运行到下面这步也会抛出空指针异常。
这里写图片描述

HashMap中,null可以作为键,这样的键只有一个;可以有一个或多个键所对应的值为null。当get()方法返回null值时,可能是 HashMap中没有该键,也可能使该键所对应的值为null。因此,在HashMap中不能由get()方法来判断HashMap中是否存在某个键, 而应该用containsKey()方法来判断。

6 线程安全性不同
Hashtable是线程安全的,它的每个方法中都加入了Synchronize方法。在多线程并发的环境下,可以直接使用Hashtable,不需要自己为它的方法实现同步

HashMap不是线程安全的,在多线程并发的环境下,可能会产生死锁等问题。具体的原因在下一篇文章中会详细进行分析。使用HashMap时就必须要自己增加同步处理,

虽然HashMap不是线程安全的,但是它的效率会比Hashtable要好很多。这样设计是合理的。在我们的日常使用当中,大部分时间是单线程操作的。HashMap把这部分操作解放出来了。当需要多线程操作的时候可以使用线程安全的ConcurrentHashMap。ConcurrentHashMap虽然也是线程安全的,但是它的效率比Hashtable要高好多倍。因为ConcurrentHashMap使用了分段锁,并不对整个数据进行锁定。

7 遍历方式的内部实现上不同
Hashtable、HashMap都使用了 Iterator。而由于历史原因,Hashtable还使用了Enumeration的方式 。

HashMap的Iterator是fail-fast迭代器。当有其它线程改变了HashMap的结构(增加,删除,修改元素),将会抛出ConcurrentModificationException。不过,通过Iterator的remove()方法移除元素则不会抛出ConcurrentModificationException异常。但这并不是一个一定发生的行为,要看JVM。

JDK8之前的版本中,Hashtable是没有fast-fail机制的。在JDK8及以后的版本中 ,HashTable也是使用fast-fail的, 源码如下:
这里写图片描述

modCount的使用类似于并发编程中的CAS(Compare and Swap)技术。我们可以看到这个方法中,每次在发生增删改的时候都会出现modCount++的动作。而modcount可以理解为是当前hashtable的状态。每发生一次操作,状态就向前走一步。设置这个状态,主要是由于hashtable等容器类在迭代时,判断数据是否过时时使用的。尽管hashtable采用了原生的同步锁来保护数据安全。但是在出现迭代数据的时候,则无法保证边迭代,边正确操作。于是使用这个值来标记状态。一旦在迭代的过程中状态发生了改变,则会快速抛出一个异常,终止迭代行为。

8 初始容量大小和每次扩充容量大小的不同
Hashtable默认的初始大小为11,之后每次扩充,容量变为原来的2n+1。HashMap默认的初始化大小为16。之后每次扩充,容量变为原来的2倍。

创建时,如果给定了容量初始值,那么Hashtable会直接使用你给定的大小,而HashMap会将其扩充为2的幂次方大小。也就是说Hashtable会尽量使用素数、奇数。而HashMap则总是使用2的幂作为哈希表的大小。

之所以会有这样的不同,是因为Hashtable和HashMap设计时的侧重点不同。Hashtable的侧重点是哈希的结果更加均匀,使得哈希冲突减少。当哈希表的大小为素数时,简单的取模哈希的结果会更加均匀。而HashMap则更加关注hash的计算效率问题。在取模计算时,如果模数是2的幂,那么我们可以直接使用位运算来得到结果,效率要大大高于做除法。HashMap为了加快hash的速度,将哈希表的大小固定为了2的幂。当然这引入了哈希分布不均匀的问题,所以HashMap为解决这问题,又对hash算法做了一些改动。这从而导致了Hashtable和HashMap的计算hash值的方法不同
9 计算hash值的方法不同
为了得到元素的位置,首先需要根据元素的 KEY计算出一个hash值,然后再用这个hash值来计算得到最终的位置。

Hashtable直接使用对象的hashCode。hashCode是JDK根据对象的地址或者字符串或者数字算出来的int类型的数值。然后再使用除留余数发来获得最终的位置。
这里写图片描述

Hashtable在计算元素的位置时需要进行一次除法运算,而除法运算是比较耗时的。
HashMap为了提高计算效率,将哈希表的大小固定为了2的幂,这样在取模预算时,不需要做除法,只需要做位运算。位运算比除法的效率要高很多。

HashMap的效率虽然提高了,但是hash冲突却也增加了。因为它得出的hash值的低位相同的概率比较高,而计算位运算

为了解决这个问题,HashMap重新根据hashcode计算hash值后,又对hash值做了一些运算来打散数据。使得取得的位置更加分散,从而减少了hash冲突。当然了,为了高效,HashMap只做了一些简单的位处理。从而不至于把使用2 的幂次方带来的效率提升给抵消掉。

这里写图片描述

附上关于这个问题的说明:
Joshua Bloch: The downside of using a power-of-two is that the resulting hash table is very sensitive to the quality of the hash function (hashCode). It is imperative that any change in the input must affect the low order bits of the hash value. (Ideally, it should affect all bits of the hash value with equal likelihood.) Because we have no assurance that this is true, we put in a secondary (or “defensive”) hash function when we switched to the power-of-two hash table. This hash function is applied to the results of hashCode before masking off the low order bits. Its job is to scatter the information over all the bits, and in particular, into the low order bits. Of course it has to run very fast, or you lose the benefit of switching to the power-of-two-sized table. The original secondary hash function in 1.4 turned out to be insufficient. We knew that this was a theoretical possibility, but we thought that it didn’t affect any practical data sets. We were wrong. The replacement secondary hash function (which I developed with the aid of a computer) has strong statistical properties that pretty much guarantee good bucket distribution.

这里写图片描述

欢迎关注个人公众号!

微信交流群
在这里插入图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

HashMap 与HashTable的区别 的相关文章

  • AutoDL跑pycharm代码

    参考文献 AutoDL帮助文档 Pycharm连接远程GPU服务器跑深度学习 哔哩哔哩 bilibili 环境包的安装在linux环境下载非常方便 安装apex 重点是将路径转换正确 参考文献 详解Apex的安装和使用教程 花开山岗红艳艳的
  • VIVADO关于VIO IP核(Virtual Input/Output)的使用

    平台 vivado2017 4 最近在验证一个单独的模块时 希望可以在线实时改变内部寄存器的值 经过分析发现 VIVADO的VIO可以完美解决我的这个问题 下面来看看官方介绍 VIO它可以实时监控和驱动FPGA内部的信号 输入和输出端口的数
  • Java EnumMap values()方法具有什么功能呢?

    转自 Java EnumMap values 方法具有什么功能呢 下文笔者讲述EnumMap values 方法的功能简介说明 如下所示 EnumMap values 方法的功能 返回一个Collection 此集合中存储EnumMap中的
  • 如何阅读英文文献,有哪些高效的方法或者辅助工具?

    每日一问 如何阅读英文文献 有哪些高效的方法或者辅助工具 Datawhale优秀回答者 追风者 方法 先是通读文献综述 理解专业术语和基本概念 起初时应以泛读为主 再研读自己研究领域的经典论文50篇 确定研究方向之后 要以精读为主 要做到边
  • 线性代数 计算机网络,计算机应用、计算机网络专业《线性代数》课程.doc

    2006级函授建筑工程 计算机应用 计算机网络专业 线性代数 课程 自 学 指 导 和 自 学 进 度 表 一 课程的目的 任务和要求 本课程是为培养建筑工程 计算机应用 计算机网络及工程等专业人才而设置的一门必修的重要基础理论课 作为信息
  • 【Redis】举例让你快速理解!Redis数据结构与命令(更新中)

    Redis 数据存内存 C语言实现 单线程架构 基于键值对 值可以为字符串 哈希 列表 集合 有序集合 键过期功能实现缓存 流水线功能减少网络开销 持久化 数据内存 gt 磁盘 主从复制 数据多副本 高可用 故障发现与自动转移 分布式 奇数
  • typescript 扩展第三方库类型,添加属性成员

    preface 之前在使用 axios 的时候 需要在 AxiosRequestConfig 中添加自定义属性 比如说 配置是否使用 loading 效果 配置 业务报错是否 自动提示 我选择了通过过 扩展接口 然后自定义了一个函数 在函数
  • 这才是CSDN最系统的网络安全学习路线(建议收藏)

    01 什么是网络安全 网络安全可以基于攻击和防御视角来分类 我们经常听到的 红队 渗透测试 等就是研究攻击技术 而 蓝队 安全运营 安全运维 则研究防御技术 无论网络 Web 移动 桌面 云等哪个领域 都有攻与防两面性 例如 Web 安全技
  • 华为hcip认证考试内容是什么?hcip认证有哪些方向

    HCIP不同方向考试的科目和内容不一样 有的需要考三门 如 HCNP Routing Switching 路由交换 HCNP Storage 存储 HCNP Security 安全 这三个方向 而其他的认证方向 有的只需要考一门的 少部分则
  • WordPress配置SMTP发送电子邮件(QQ邮箱)

    Wordpress通过PHP自带的mail函数实现电子邮件的发送成功率极低 现有的各类邮箱 例如QQ邮箱 新浪邮箱 163邮箱等 基本不支持PHP语言的mail函数实现的邮件发送 因此 需要配置基于SMTP协议的邮件发送环境 实现Wordp
  • 软件工程基础知识--软件项目管理

    软件项目管理是指软件生存周期中软件管理者所进行的一系列活动 其目的是在一定的时间和预设范围内有效地利用人力 资源 技术和工具 使软件系统或软件产品按原定计划和质量要求如期完成 一 软件项目管理涉及范围 二 软件项目估算 三 进度管理 四 软
  • AutoCAD 2021 for Mac(cad2021)中文版

    AutodeskAutoCAD 2021中文版目前已经正式发布了 CAD2021 全称为AutoCAD2021 这是目前Autodesk公司最新发布的一款非常好用且功能强大二维和三维CAD设计软件 同时该软件内置了专业强大的MEP MAP
  • Linux 之大数据定制篇-Shell 编程

    Linux 之大数据定制篇 Shell 编程 为什么要学习Shell 编程 Linux 运维工程师在进行服务器集群管理时 需要编写Shell 程序来进行服务器管理 对于JavaEE 和Python 程序员来说 工作的需要 你的老大会要求你编
  • 【音视频流媒体】1、图像YUV、视频编码H264、封装格式 FLV、网络协议RTSP 超详细介绍

    文章目录 一 从参数看视频图像 1 1 像素 1 2 分辨率 1 3 位深 1 4 stride 1 5 帧率 fps 帧 秒 1 6 码率 Kb s Mb s 二 颜色空间 YUV RGB YUV4 4 4 YUV4 2 2 YU16 或
  • Java jsp cannot be resolved to a type解决方法之一

    不要在一个文件夹下面建两个名字一样的包和类
  • 团队管理的四大挑战——招人篇

    团队管理的四大挑战 招人篇 招人篇 1 告诉 HR 你的团队需要什么样的人 2 尊重应聘者 3 你不需要套路 4 互补而不是趋同 5 如果犹豫 那么放弃 6 如何面试比你高阶的人 7 面试最重要的目的是识别风险 8 缺点易现 亮点难得 结语
  • 【chineseOCR】踩过的坑

    1 环境 ubuntu16 04 cuda10 tensorflow1 13 2 web py 0 40 dev0 这两个比较重要 不然会报好多奇怪的错 说明tensorflow必须1 13版本 低了不支持cudn10 高了chineseO
  • Android自定义轮播效果(优化)

    创作背景 本文是继上一篇 Android自定义轮播效果 优化问题而写 希望大家能有顺序的看 优化一 实现自动无线轮播 private class myPagerAdapter extends PagerAdapter Override pu
  • 【知识点】单片机USB转TTL模块的相关知识

    前言 USB转TTL模块的作用就是把电平转换到双方都能识别进行通信 单片机通信接口的电平逻辑和PC机通信接口的电平逻辑不同 PC机上的通信 接口有USB接口 相应电平逻辑遵照USB原则 还有DB9接口 九针口 相应电平逻辑遵照RS 232原

随机推荐

  • MFC的Brush与Pen的使用

    Brush的使用 void CMFCApplicationDlg OnBnClickedOk CDC pDC GetWindowDC CBrush brush1 Must initialize brush1 CreateSolidBrush
  • SonarQube代码质量检测的一点坑

    这里解决的问题有以下几点 1 之前用过sonarqube检测过代码的质量 因其自带的CFamily需要license 故在github上找到相关开源免费的C C 插件 针对特定的sonarqube版本都有相对应的sonar cxx c版本
  • 原生js实现导航条动画

    原生js实现毛毛虫导航 直接上代码
  • 计算机毕业设计选题推荐基于nodejs+Vue360学生宿舍系统

    管理员 首页 个人中心 宿舍信息管理 学生管理 宿舍报修管理 访客信息管理 水电费管理 管理员管理 交流论坛 系统管理 学生 首页 个人中心 宿舍报修管理 水电费管理 前台首页 首页 交流论坛 通知公告 个人中心 后台管理 在线沟通等 目
  • win 10 下cmd命令无法使用ssh命令

    在WIN 10 系统下出现cmd命令无法正常使用ssh命令 提示 ssh不是内部命令 出现这种情况要考虑到是环境变量出现问题 1 鼠标右键单击 我的电脑 进入 属性 2 点击 系统高级设置 选择 环境变量 3 找到 path 点击打开 4
  • Qt中使用QTextStream中文乱码的情况解决

    1 前言 今天在做一个文件编辑器 然后发现读取txt文件的时候 中文的显示乱码 然后在网上查了一些方法 没用 自己摸索了一下 找出了一个办法 2 解决办法 QTextStream in new QTextStream file in gt
  • Csharp:TinyMCE HTML Editor in .NET WindowsForms

  • STM32控制电机简易教程

    STM32控制电机简易教程 包教包会 近期 电赛临近 来补习一下电机的使用方式 使用起来非常的方便 首先是在CUBEMX里面配置一些基本内容 然后是使用PWM去调速 其他的时钟和调试配置就不多说了 然后就是初始化了 同样的 这里使用的是结构
  • 【华为OD机试真题 python】最大报酬【2022 Q4

    题目描述 最大报酬 小明每周上班都会拿到自己的工作清单 工作清单内包含 n 项工作 每项工作都有对应的耗时时间 单位 h 和报酬 工作的总报酬为所有已完成工作的报酬之和 那么请你帮小明安排一下工作 保证小明在指定的工作时间内工作收入最大化
  • 如何在SYSTEM权限下实现屏幕监控

    屏幕监控是远控软件的基本功能之一 现在很多远控程序的服务端通常为DLL形式 通过远程线程注入等方法插入到services svchost等SYSTEM权限的进程中去 而此时常规的屏幕监控就会失效 这是因为与SYSTEM权限进程关联的窗口站
  • Springboot 各种常用配置

    目录 数据库配置 常用 sql 数据源 spring 配置 druid 依赖 基础配置 统一错误处理 统一响应信息处理 Swagger 配置 Spring security 配置 抽象业务配置 实体类的父类 控制器父类 mybatis pl
  • 【统计模型】ToothGrowth数据集双因素方差分析

    目录 ToothGrowth数据集双因素方差分析 一 研究目的 二 数据来源和相关说明 三 描述性分析 3 1 样本描述 3 2 样本均值 3 3 箱线图 四 数学建模 五 结论与建议 5 1 结论 5 2 建议 六 代码 ToothGro
  • 111. 二叉树的最小深度

    给定一个二叉树 找出其最小深度 最小深度是从根节点到最近叶子节点的最短路径上的节点数量 说明 叶子节点是指没有子节点的节点 Definition for a binary tree node public class TreeNode in
  • android so劫持,防劫持SDK

    防劫持SDK 一 产品简介 防劫持SDK是具备防劫持兼防截屏功能的SDK 可有效防范恶意程序对应用进行界面劫持与截屏的恶意行为 二 iOS版本 2 1 环境要求条目说明兼容平台iOS 8 0 开发环境XCode 4 0 CPU架构armv7
  • 四、设计工程

    软件设计开始于软件需分析和规约之后 是把需求转化为软件系统的重要环节 软件需求解决 做什么 的问题 软件设计解决 怎么做 的问题 一 概述 早期设计工程分为概要设计和详细设计 概要设计 将需求转换为数据结构 软件体系结构及其接口 详细设计或
  • 另一种排序方法 C#

    private void button27 Click object sender EventArgs e int array new int 10 3 2 4 90 50 20 34 22 49 int newArray new int
  • 125道Python面试题总结

    Pyhton面试宝典 提高编程能力的最有效办法就是 敲代码 1 一行代码实现1 100之和 res sum range 1 101 print res 5050 Python精华知识点手册 完整版 下载 2 如何在一个函数内部修改全局变量
  • Java嵌入式数据库H2学习总结(一)——H2数据库入门

    只为成功找方法 不为失败找借口 Java嵌入式数据库H2学习总结 一 H2数据库入门 一 H2数据库介绍 常用的开源数据库有 H2 Derby HSQLDB MySQL PostgreSQL 其中H2和HSQLDB类似 十分适合作为嵌入式数
  • ios(六)sqlite3以及FMDB

    SQLite 一种轻量的本地数据库 方便嵌入系统 支持跨平台 根据工作经验来看 无论是Android还是iOS大多都采用SQLite 首先我们需要新建一个数据库 我们给他起名personinfo sqlite 创建一张叫做person的表
  • HashMap 与HashTable的区别

    HashMap 与HashTable的区别 HashMap与Hashtable的区别是面试中经常遇到的一个问题 这个问题看似简单 但如果深究进去 也能了解到不少知识 本文对两者从来源 特性 算法等多个方面进行对比总结 力争多角度 全方位的展