带着问题学习?
HashMap用了什么数据结构?
HashMap线程安全吗?
- 如果
HashMap存储的数量超过了设置的上限会怎么样?
HashMap中的负载因子是干嘛的?
HashMap在使用数组+链表的结构时,新插入的节点是头插入还是尾插入?
HashMap在使用数组+红黑树结构时,如果扩容,怎么保证树的结构不变?
- 在什么情况下,会从 链表 转成 红黑树 存储?
- 在什么情况下,会从 红黑树 转成 链表 存储?
介绍
HashMap是 Java 中提供的一种Map集合,继承自AbstractMap,同时实现了Map接口
- 其中
AbstractMap提供了一套Map的基础模板,其中定义了包括get()、put()、containsKey()之类的方法(这也体现了 抽象类是模板,接口是规范 的说法)
源码解析
HashMap 的基本定义:
HashMap 中,默认定义了一下参数,这使得我们可以直接使用 空构造 方法 来创建 HashMap 实例,并且正常使用HashMap 中数据存储的格式
- 在
HashMap中,并不是直接存储我们的键值对的,而是用一个结构Node,把我们的键值对存放进去,并且在其中存放该节点的hashCode和 下一个节点的指针
- 看看具体定义:
HashMap 求 hashcode 的方法
HashMap 存键值对的过程
- HashMap 中添加键值对的方法是
put()
- 看看源码定义
链表转变为树的过程
- 当哈希冲突链表长度达到阈值时,会将链表转换为红黑树
- 看源码定义
树退化为链表的过程
- 当哈希表中的红黑树节点数小于等于设置的 阈值 时,
HashMap会将整个红黑树退化为链表,以节省空间和时间消耗
- 看看代码定义:
HashMap 中的扩容机制
- 在
HashMap中,如果其内的元素个数超过了设置的容量大小,就进行扩容,每次都是翻大2^m被
- 看看代码定义:
问题解答
HashMap 用了什么数据结构?
当单条哈希冲突链表的长度大于
TREEIFY_THRESHOLD 时,就是 数组+红黑树,否则就是 数组+链表HashMap 线程安全吗?
不安全的,因为在
put 之类的操作时,没有进行相应的同步机制如果 HashMap 存储的数量超过了设置的上限会怎么样?
- 如果还没到
Integer.MAX_VALUE,就进行扩容,一般是扩大一倍
- 如果达到
Integer.MAX_VALUE,就没法扩容
HashMap 中的负载因子是干嘛的?
作为是否扩容的一个决定因子,当哈希表中元素数量达到了负载因子乘以数组容量时,就需要进行扩容操作
HashMap 在使用数组+链表的结构时,新插入的节点是头插入还是尾插入?
尾插
在什么情况下,会从 链表 转成 红黑树 存储?
在单条哈希冲突链表的长度超过
TREEIFY_THRESHOLD 时在什么情况下,会从 红黑树 转成 链表 存储?
在单个哈希冲突红黑树中的元素个数小于
UNTREEIFY_THRESHOLD 时推荐/参考
- Author:CoderWdd
- URL:https://www.wuinsights.top//article/df20b434695d
- Copyright:All articles in this blog, except for special statements, adopt BY-NC-SA agreement. Please indicate the source!
Relate Posts