当前位置: 首页 > news >正文

HashMap 和 Hashtable区别的底层原理

一、容器键值对:
1.HashMap 的 key 和 value 都允许为 null , HashMap 在 key 为 null 的时候,值必须为null。
2.Hashtable 的 key 和 value 都不允许为 null 。 Hashtable 遇到key或value为 null时 ,将抛出 NullPointerException异常 。


二、容量设定与扩容机制:
1.HashMap 默认初始化容量为 16,并且容器容量一定是 2 的 n 次方。当元素数量达到容量和加载因子(加载因子LoadFactor,默认为0.75)的乘积时会触发扩容,并且是以原容量 2 倍 的方式 进行扩容。
2.Hashtable 默认初始化容量为 11。
在元素数量达到容量和加载因子(加载因子默认是0.75)的乘积时会进行扩容,是以原容量 2 倍 再加 1 的方式进行扩容。即 int newCapacity = (oldCapacity << 1) + 1; 。


三、存储位置:
1.HashMap 是先将 key 键的 hashCode 经过扰动函数扰动后得到 hash 值,然后再利用  hash & (length - 1) 的方式(由于 HashMap 的容器容量一定是 2 的 n 次方,所以可以使用 hash & (length- 1) 的方式代替取模的方式计算元素的位置从而提高运算效率)代替取模,得到元素的存储位置。JDK 1.8之后HashMap引入了红黑树来优化链表过长的问题。
2.Hashtable 是使用除留余数法进行计算存储位置的(因为其默认容量不是2 的 n 次方,故无法用位运算替代模运算), int index = (hash &0x7FFFFFFF) % tab.length; 。


四、线程安全:
1.HashMap 不是线程安全,如果想线程安全,可以通过调用Collections.synchronizedMap(Map<K,V> m) 使其线程安全。或使用 ConcurrentHashMap 容器以同样达到线程安全。
2.Hashtable 是线程安全的,每个操作方法都有 synchronized 修饰使其同步,但运行效率不高,所以建议使用 ConcurrentHashMap 容器以达到线程安全。
3.总结:
1)Hashtable 是一个古老的容器,如果我们不需要线程同步,则可以使用HashMap ,如果需要线程同步,则可以使用 ConcurrentHashMap 。
2)HashMap不是同步的,所以性能会比Hashtable要高。


五、遍历及访问
1.HashMap和Hashtable都支持使用Iterator进行遍历。但是,Hashtable还额外支持使用Enumeration进行遍历,但此方式已过时。
2.HashMap 的迭代器(Iterator)是 fail-fast 的。如在迭代过程中需要修改 HashMap的结构,除了通过迭代器的 remove() 方法是安全的之外,调用其他方法都会抛出 ConcurrentModificationException 异常。
Hashtable 的迭代器不是 fail-fast 的。
3.HashMap迭代顺序不确定。Hashtable迭代顺序按照插入顺序进行。
4.Hashtable保留了containsKey、containsValue、contains三个方法,用于检查是否包含某个键、值或键值对。
HashMap去掉了contains方法,只保留了containsKey和containsValue两个方法。


六、其他
1.HashMap继承自AbstractMap,实现了Map、Cloneable、Serializable接口。
2.Hashtable继承自Dictionary,实现了Map、Cloneable、Serializable接口。
 


微风不燥,阳光正好,你就像风一样经过这里,愿你停留的片刻温暖舒心。

我是程序员小迷(致力于C、C++、Java、Kotlin、Android、Shell、JavaScript、TypeScript、Python等编程技术的技巧经验分享),若作品对您有帮助,请关注、分享、点赞、收藏、在看、喜欢,您的支持是我们为您提供帮助的最大动力。

欢迎关注。助您在编程路上越走越好!

http://www.lryc.cn/news/347798.html

相关文章:

  • 代码随想录35期Day32-Java
  • ROS 2边学边练(45)-- 构建一个能动的机器人模型
  • 【第66例】IPD体系进阶:华为IPD发展历程
  • websevere服务器从零搭建到上线(四)|muduo网络库的基本原理和使用
  • C语言笔记10
  • BMS-HiL主要功能
  • idea无法识别加载pom.xml文件
  • C语言笔记12
  • 说一下 hibernate 的缓存机制?
  • Mac安装jadx
  • 风扇开启执行逻辑
  • 调用函数实现数组的输入排序插入与输出
  • 代码随想录算法训练营Day 41| 动态规划part03 | 343. 整数拆分、96.不同的二叉搜索树
  • 多模态产品在智能文档处理应用的展望------以TextIn模型为例
  • 上海市计算机学会竞赛平台2024年3月月赛丙组最近的数字
  • RFID在汽车制造中的应用如何改变行业
  • sCrypt受邀在中国人民大学举办《区块链与数字经济》课程讲座
  • pc端的鼠标箭头变换
  • ICode国际青少年编程竞赛- Python-2级训练场-for循环练习2
  • RiPro主题美化【支付弹窗底部提示语根据入口不同有不同的提示】ritheme主题美化RiProV2 增加支付提示语,按支付类型不同,入口不同提示语不同的设置
  • MSMQ消息队列
  • 树莓派nmap扫描
  • 【必看】Spring系列面试题
  • wordpress增加谷歌分析
  • linux的信号量的使用
  • C--贪吃蛇
  • element ui的确认提示框按钮样式修改
  • 【vue】keep-alive:true缓存导致页面数据不刷新
  • Golang — map的使用心得和底层原理
  • Oracle如何收缩减小表空间大小