集合之HashMap 1.7总结

news/2024/11/27 8:44:44/

文章目录

    • 底层数据结构:
    • HashMap有什么特点?
    • HashMap 1.7 是如何解决Hash冲突的?
    • HashMap 1.7 是如何降低Hash冲突概率的?
    • HashMap 的长度为什么是2的幂次方?
    • HashMap 容量应该如何设置?
    • 高并发下如何使用HashMap?
    • HashMap在高并发下为什么不安全?
    • 总结的put()和get()方法的流程图

底层数据结构:

	数组+链表数组特点:根据下标定位,一般情况下查询、修改快于链表。链表特点:连接元素通过指针,新增和删除只需变更指针连接即可,所以一般情况下增删快,查询因需要遍历链表,所以查询效率一般慢于数组。

HashMap有什么特点?

​ 无序,散列存放,遍历结果与存储顺序不一定一致。

​ 如果需要有序存放,可以使用LinkedHashMap来存放元素。

HashMap 1.7 是如何解决Hash冲突的?

采用链地址法来存储发生Hash冲突的元素。

HashMap 1.7 是如何降低Hash冲突概率的?

  • 使用2的幂次方作为容量,计算时使用len-1与key的hash做与运算,减少hash冲突的概率。
  • 高16位做异或运算,(h = key.hashCode()) ^ (h >>> 16)。

HashMap 的长度为什么是2的幂次方?

  • 为了减少Hash碰撞,使Hash计算结果更均匀。
  • 做与运算时,我们需要取数组长度-1,比如使用默认长度16,那么参与与运算的值为15,15的二进制为0000 1111,此时,参与与运算后得到的key的位置还是key本身,这样可以使key分布的更均匀。

HashMap 容量应该如何设置?

  • 參考阿里巴巴开发手册,集合初始化时,应该指定初始值大小。
  • initialCapacity = (需要存储的元素个数 / 负载因子) + 1。注意负载因子(即loader factor)默认为0.75, 如果暂时无法确定初始值大小,请设置为16(即默认值)。
  • 如果存储1W个key,那么按照公式:i = 10000/0.75 +1 =13334个。如果不设置初始容量,则需要扩容10次左右,影响效率。

高并发下如何使用HashMap?

  • 线程安全的集合类主要包括了三大类:
    • 遗留的线程集合类如Hashtable、Vector;性能较低
    • Collections修饰的线程安全集合类如synchronizedMap;使用synchronized修饰来保证线程安全。
    • JUC包下的安全类。
  • 高并发下推荐使用ConcurrentHashMap来保证线程安全。

HashMap在高并发下为什么不安全?

  • 数据覆盖问题

    • 高并发下两个线程同时做put操作,当key相等时,第二个线程可能会覆盖第一个线程的值。
  • 循环链表问题

    • 此问题主要发生于扩容时。链表使用了头插法,在扩容时可能会导致原有的链表顺序逆转。

      举例:比如原先链表为a-b-c-null,此时需要扩容,有两个线程同时扩容,第一个线程执行一半因为某种原因卡住了,此时线程2开始执行,执行完成后,c又指向了a,此时线程1恢复执行,本来线程1执行到c后,下一个元素为null,就会停止执行,但是受到线程2的影响此时c指向了a,所以继续执行,就构成了循环链表。

    • 导致的问题:在put或get方法时,会遍历链表,但此时链表构成了循环,所以会一直遍历,导致死循环,逐渐CPU占用会达到100%居高不下。

  • 数据get()为null的情况

    • 当并发操作时,此时有两个线程,一个执行get方法,一个执行put方法,此时执行put方法导致了扩容,会创建一个新数组,引用会赋给新数组,此时可能数据还没有移动到新数组,如果此时执行get方法,那么取到的值可能为空。

总结的put()和get()方法的流程图

  • PUT方法:

请添加图片描述

  • GET方法:
    请添加图片描述

http://www.ppmy.cn/news/35013.html

相关文章

DNS主从复制

#前提准备:关闭SElinux 关闭防火墙 时间同步 #环境说明:Centos7 #ip地址:dns-master:10.0.0.100 dns-slave:10.0.0.103 web:10.0.0.101 主DNS服务配置 1.安装软件包: yum install bind -…

学习 Python 之 Pygame 开发魂斗罗(十三)

学习 Python 之 Pygame 开发魂斗罗(十三)继续编写魂斗罗1. 创建敌人2类2. 编写敌人2类的draw()函数3. 编写敌人越界消失函数4. 编写敌人开火函数5. 把敌人2加入地图进行测试继续编写魂斗罗 在上次的博客学习 Python 之 Pygame 开发魂斗罗(十…

乐观锁和悲观锁 面试题

Mysql的乐观锁和悲观锁 实现方式加锁时机常见的调用方式优势不足适用场景乐观锁开发自定义更新数据的时候sql语句中进行version的判断高并发容易出现不一致的问题高并发读,少写悲观锁Mysql内置查询数据的开始select * for update保证一致性低并发互联网高并发场景极…

基于Golang实现多人在线游戏的AOI算法

1、AOI基本介绍 游戏的AOI(Area of Interest)算法应该算作游戏的基础核心了,许多逻辑都是因为AOI进出事件驱动的,许多网络同步数据也是因为AOI进出事件产生的。因此,良好的AOI算法和基于AOI算法的优化,是提高游戏性能的关键。 为…

ubuntu下使用GCC开发单片机的过程

以下是一个简单的单片机C程序示例,实现的功能是控制LED灯的闪烁: #include <reg52.h> // 导入单片机的寄存器定义void main() {while(1) { // 无限循环P1 = 0x00; // P1口输出低电平delay(1000); // 延时1秒P1 = 0xff; // P1口输出高电平delay(1000); // 延时1秒…

[刷题]背包问题

递归问题特性 ①问题有最优子结构&#xff1a;问题存在最优解&#xff0c;且与其子问题最优解重合 ②无后效&#xff1a;前后状态值只和值本身有关&#xff0c;和问题无关。 解决思路&#xff1a; ①将原问题分解为子问题 ②确定状态 ③确定初始状态值 ④确定状态转移方程&…

b01lers(php.galf)

目录 前文 正文 前文 <?phpclass A{public $codeNULL;public $argsNULL;public function __construct($code,$argsNULL){$this->code$code;$this->args$args;print_r("2333") ;} public function __invoke($code,$args){echo $code;print_r("执行inv…

[入门必看]数据结构2.3:线性表的链式表示

[入门必看]数据结构2.3&#xff1a;线性表的链式表示第二章 线性表2.3 线性表的链式表示知识总览2.3.1 单链表的定义2.3.2_1 单链表的插入删除2.3.2_2 单链表的查找2.3.2_3 单链表的建立2.3.3 双链表2.3.4 循环链表2.3.5 静态链表2.3.6 顺序表和链表的比较2.3.1 单链表的定义单…