jdk1.8中HashMap的扩容,从新增第一个元素开始

2023-05-16

置灰部分在当前场景下不考虑

1.新增第一个元素

新增第一个元素总结:

先进行数组容量初始化,初始大小为16,扩容界限为12,再找出数组对应位置,将新增的值放入。


2.继续新增元素,假设一直不产生hash冲突

 

 

 

执行完一系列操作,也就完成了数组的扩容,【注:此处还未涉及到hash冲突】

不产生hash冲突总结:

当新增的元素达到了该扩容的界限,那么会触发扩容操作,先计算扩容后的大小,也就是原数组大小的两倍,然后创建一个新容量大小的数组,再进行原数组遍历依次定位后放入新数组中。

 

非树情况下产生hash冲突总结

先确定在数组中的位置,如果该位置上已经存在元素,再判断是否key相同,如果不相同,那么获取到该位置上的尾节点,将尾节点的next指向新增的节点。当达到新增完后,发现容量大小已经超过阈值,那么开始进行扩容,扩容先产生一个原数组两倍大小的新数组,再遍历原数组,

如果遍历到的位置只有一个节点,将该节点的hash值和(新数组容量大小值-1)进行&操作定位。

如果遍历的位置是链表结构,那么依次遍历链表到末尾,期间将节点的hash和原数组容量大小进行&操作,如果高位是0,则原位置不变,如果高位是1,则新位置=(当前位置+原数组容量大小)

 

整体步骤

1.创建hashMap,

2.新增第一个元素,先进行数组容量初始化,初始化大小为16,扩容触发的阈值为12,然后将元素插入该数组中。

3.后续依次加入元素,假如新增一直没有产生hash冲突,新增完后,判断大小却达到了阈值12,那么触发数组扩容。扩容大小为原大小的2倍,也就是32,阈值扩大两倍为24。然后进行元素的重定位【但其实只是个元素的hash和(容量大小-1的值)进行与操作,这样操作的话位置不变】。

4.然后如果一直新增元素,产生hash冲突,那么先找到冲突位置的首节点,然后将新增的节点挂在尾结点,当改链路下的长度>=8,且当下的数组大小还没超过64,那么先进行扩容操作,扩容就是遍历原数组,当元素只有一个节点,则如上描述的扩容走,当元素为链表,则对元素和原数组大小进行与操作,值要么是0,要么是原数组大小,所以,要么位置不变,要么位置在原基础上加上原数组大小。

5.然后又一直加元素,加到数组容量超过了64,且其中存在的链表结构长度>=8,则进行链表转红黑树的操作。其中,红黑树在扩容的时候,碰到深度<=6的会将其转回链表

 

注:

1.扩容元素时不需要重新计算hash值

2.满足链表转红黑树的两个条件

     数组大小>=64【容易忽略这一点】

     链表长度>=8

3.红黑树什么时候转回链表

 

 

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

jdk1.8中HashMap的扩容,从新增第一个元素开始 的相关文章

  • 将 HashMap 内容写入文件

    我有一个HashMap
  • 2d(3d) 坐标的哈希图(即双精度向量)?

    我想知道是否有一个通用的全能解决方案hash map对于坐标 2d 或 3d 即双精度向量 一个例子here https stackoverflow com questions 7222143 unordered map hash func
  • 根据键名从 HashMap 获取字符串值

    我有一个HashMap有各种键和值 我怎样才能得到一个值 我在地图上有一把钥匙叫my code 它应该包含一个字符串 我怎样才能得到它而不必遍历地图 到目前为止我已经 HashMap newMap new HashMap paramMap
  • 最坏情况时间复杂度 put/get HashMap

    当 Hashmap 的键的哈希码始终相等时 它的最坏情况时间复杂度是多少 根据我的理解 由于每个键都有相同的哈希码 因此它总是会进入同一个存储桶并循环遍历它以检查 equals 方法 因此对于 get 和 put 时间复杂度应该是 O n
  • 何时使用 HashMap 而不是 LinkedList 或 ArrayList,反之亦然

    为什么我们不能总是使用 HashMap 尽管它在添加 删除操作上比 ArrayList 或 LinkedList 高效得多 而且与元素的数量无关 我用 google 搜索了一下 发现了一些原因 但使用 HashMap 总有一种解决方法 而且
  • 如何按整数值对哈希图进行排序[重复]

    这个问题在这里已经有答案了 HashMap
  • JAXB 将 XML 元素解组到 HashMap

    我发现很多文章描述了如何将 XML 元素序列解组到 HashMap 只要它们位于 父 元素内 但是 我无法将此与直接在根元素下的子元素一起使用 选项 1 有效
  • 地图中的最大元素数

    GO 中的 Map 最多可以存储多少个元素 如果我需要经常从 Map 访问数据 那么在长时间运行的程序中不断向 Map 添加项目并从中检索项目是一个好主意吗 除了map length类型的最大值之外 map中的元素数量没有理论上的限制 in
  • 初始化 HashMap 的最佳方法

    我通常会这样做 HashMap
  • HashSet如何不允许重复?

    我正在经历add的方法HashSet 值得一提的是 如果该集合已包含该元素 则调用将保持该集合不变并返回 false But the add方法在内部保存值HashMap public boolean add E e return map
  • 在哈希图中存储字符和二进制数

    我正在尝试存储字母到二进制数的映射 这是我的映射 h 001 i 010 k 011 l 100 r 101 s 110 t 111 为此 我创建了一个哈希映射并存储了键值对 我现在想显示给定句子的相应二进制值 这是我的代码 package
  • 在 Python 中进行模糊键查找的最佳方法?

    我遇到一个问题 我需要在哈希映射中进行模糊查找 即返回与最接近查询的键相对应的值 在我的例子中是通过 Levenshtein 距离测量的 我目前的方法是子类化dict使用特殊的查找方法计算所有键的编辑距离 然后返回得分最低的键的值 基本上是
  • Python 中的哈希映射

    我想用Python实现HashMap 我想请求用户输入 根据他的输入 我从 HashMap 中检索一些信息 如果用户输入HashMap的某个键 我想检索相应的值 如何在 Python 中实现此功能 HashMap
  • HashMap不写入数据库

    我尝试在我的数据库中写入 但只写入发件人和消息 我不明白为什么会发生这种情况 我认为问题出在我使用 sendMessage 的地方 我认为问题是我没有什么可以做的读 写其他用户的主键 我在数据库中写入消息的活动 public class M
  • JQuery $.ajax() 在 java servlet 中发布数据

    我想将数据发送到 java servlet 进行处理 数据将具有可变长度并采用键 值对 A1984 1 A9873 5 A1674 2 A8724 1 A3574 3 A1165 5 数据不需要这样格式化 这就是我现在的方式 var sav
  • 添加到 HashMap 中的列表的快捷方式

    我经常需要获取一个对象列表 并根据对象中包含的值将它们分组到一个 Map 中 例如 按国家 地区获取用户和组列表 我的代码通常如下所示 Map
  • 如何在 Java 中访问嵌套的 HashMap?

    我有一个 Java 中的 HashMap 其中的内容 你们可能都知道 可以通过以下方式访问 HashMap get keyname 如果一个 HashMap 位于另一个 HashMap 中 即嵌套的 HashMap 我将如何访问内容 我可以
  • 从 HashMap 条目列表中删除重复项

    我有一个List
  • 在 C++ 中为哈希映射提供复合键

    我有一个数据结构
  • 为什么HashMap不能保证map的顺序随着时间的推移保持不变

    我在这里阅读有关 Hashmap 和 Hashtable 之间的区别 http javarevisited blogspot sg 2010 10 difference Between hashmap and html http javar

随机推荐