首页 > 其他分享 >【hashMap扩容】关于hashMap扩容以后,新下标的理解

【hashMap扩容】关于hashMap扩容以后,新下标的理解

时间:2025-01-03 19:22:27浏览次数:6  
标签:扩容 下标 hash hashMap newTab 链表 新下 oldCap

首先我们知道hashMap在存取元素的时候的下标算法是这样子的

根据当前元素(e)的hash值((e.hashCode()) ^ (e.hashCode() >>> 16))去上当前hashMap的容量减一(Cap-1)

put和get都是如此

put

 get

所以在扩容算法中,元素的坐标也应是用这种方式存的,看一下代码

我们会发现,

当,当前元素不存在链表的小尾巴时,他放入扩容以后的新数组(newTab),计算下标的时候,使用的还是很直白的方式,即元素hash值与上新数组的容量减一(newCap - 1);

当,当前元素是存在链表结构的时候,会用元素hash与上老数组的容量(oldCap),根据结果是否为0,来拆分成高位链表(hiHead->hiTail)和低位链表(loHead->loTail),并,分别存入到新数组的高位(newTab[j + oldCap])和低位(newTable[j]);

以前我看的时候只知道是把长链表拆了两段分别放入新数组,没有想过为什么要根据e.hash() & oldCap == 0 来拆分,为什么新数组的下标可以直接写成 newTab[j] 和 newTab[j + oldCap];

这是我想记下来的;

-------------------------------------------

这里举个例子方便理解,比如原来的oldCap是16 (0001 0000(这里只写8位)),现在的newCap是32(0010 0000)

先看e.hash() & oldCap == 0,根据结果是否为0判断,其实就是判断下标为4的位是否为0;

如果为0,那就说明e.hash() & (oldCap - 1) == e.hash() & (newCap - 1)  //  下标位4的位为0时 & 0000 1111  & 0001 1111 相同

因此可以直接把原先老数组的下标j直接带入到新的数组,也就是newTab[j] = loHead;

 

同时,看高位链表的下标,j + oldCap  等于  e.hash() & (oldCap - 1) + oldCap,

等于 e.hash() & 0000 1111 的值 加上 0001 0000,

等于 e.hash() & 0001 1111,

等于 e.hash() & (newCap - 1) // 直白的下标写法

所以newTab[e.hash() & (newCap - 1)] 在这里才可以被表示成newTab[j + oldCap]

 

//想到了就先记下来,怕我以后会忘记

 

标签:扩容,下标,hash,hashMap,newTab,链表,新下,oldCap
From: https://www.cnblogs.com/ffyg/p/18650348

相关文章

  • Linux上磁盘扩容
    【后端】Linux上磁盘扩容Centos7硬盘扩容第一步:查看硬盘情况 命令:lsblk 第二步:查看磁盘空间大小,命令:df-h   第三步:增加磁盘空间,使用下图vm虚拟机增加方式。物理机直接按照挂在上去。 第四步:使用fdisk/dev/sda创建新分区 ......
  • 如何在线扩容阿里云服务器云盘?
     第一、查看磁盘使用情况。如下我的系统盘已经快满了,79%使用了。[root@iZbpfrxxxxxxxxxxtgZcsp]#df-hFilesystemSizeUsedAvailUse%Mountedondevtmpfs3.8G03.8G0%/devtmpfs3.8G03.8G0%/dev/shmtmpfs3.8G......
  • 八股day1——HashMap
    HashMap回答重点数组+链表+红黑树超过负载因子会*2扩容,扩容操作比较耗时尾插法,头插法在多线程中可能会形成回路,可以参考BV1n541177Ea红黑树优化当链表长度超过8时,链表会转变为红黑树,查找复杂度从O(n)降到O(logn),如果树中元素低于6,则转换回链表,减少不表的树操作开销hashC......
  • HashMap 在高并发场景下可能出现的性能问题以及如何规避这些问题
    HashMap在容量不够进行resize时由于高并发可能出现死链,导致CPU飙升,为了避免这种情况的发生,建议在高并发场景下,可以使用其他数据结构来替代HashMap,比如ConcurrentHashMap,它是一种线程安全的哈希表实现,在高并发情况下能够保证并发性能和数据一致性。另外,还可以通过加锁的方式......
  • GPT 非LVM分区划分 以及 相邻分区扩容
    分区[root@pgsql~]$lsblk/dev/sdf可以看到新增盘sdf40G启动parted并选择磁盘parted/dev/sdf(parted)select/dev/sdf创建GPT分区表(parted)mklabelgptmkpartprimary0gb10gbmkpartprimary10gb20gbqmkdir-p/data7mkfs.ext4/dev/s......
  • 【Rust自学】8.6. HashMap Pt.2:更新HashMap
    8.6.0.本章内容第八章主要讲的是Rust中常见的集合。Rust中提供了很多集合类型的数据结构,这些集合可以包含很多值。但是第八章所讲的集合与数组和元组有所不同。第八章中的集合是存储在堆内存上而非栈内存上的,这也意味着这些集合的数据大小无需在编译时就确定,在运行时它们......
  • 如何解决服务器空间扩容后FTP无法上传文件及宝塔面板容量未更新的问题?
    您好,根据您的描述,在升级服务器空间容量后,您遇到了FTP无法上传文件以及宝塔面板显示的容量未更新的问题。以下是详细的解决方案和建议:确认磁盘扩容是否成功:首先,确保服务器提供商确实已经完成了磁盘扩容操作。可以通过服务商的管理控制台或联系技术支持确认扩容状态。使用命令......
  • 如何解决数据盘扩容后磁盘空间未合并的问题?
    您好,当数据盘扩容后磁盘空间未合并时,通常是因为操作系统未能自动识别新增加的空间。以下是详细的排查步骤和解决方案:检查磁盘分区表:首先,使用命令行工具(如fdisk-l或lsblk)查看当前磁盘分区表,确认新增加的空间是否已被识别。如果看到未分配的空间,说明下一步需要进行分区扩展操作......
  • 云服务器数据盘扩容失败,如何解决?
    您好,在处理云服务器数据盘扩容时,遇到扩容未成功的情况是比较常见的。为了确保您的数据安全并顺利解决问题,建议您按照以下步骤进行排查和操作:确认扩容操作是否正确执行首先,请确认您是否已经按照官方文档中的说明正确执行了扩容操作。通常情况下,扩容操作需要通过控制台或命令行工......
  • 服务器升级后磁盘空间未显示增加,如何手动扩容?
    当您完成服务器磁盘升级后,发现后台显示的磁盘空间并未增加,这通常是因为系统内部尚未自动扩展新分配的空间。为了使新增加的磁盘空间生效,您需要手动进行磁盘扩容操作。以下是详细的步骤和注意事项:确认磁盘升级已完成:首先,确保您的磁盘升级订单已经完成,并且支付成功。您可以登录......