由红黑树引出的HashMap扩容机制的思考

红黑树是什么?

三大特点:

  1. 根节点是黑色,叶节点是不存储数据的黑色空节点

  2. 任何相邻的两个节点不能同时为红色

  3. 任意节点到其可到达的节点间包含相同数量的黑色节点

联想:Java HashMap底层红黑树原理

HashMap基于哈希表Map接口实现,是以key-value存储形式存在,即主要用于存储键值对。

HashMap特点:

  1. 存取无序

  2. 键和值位置都可以为null,但是键的位置为null只能有一个

  3. 键位置是唯一的,底层数据结构控制键

哈希冲突:

定义:两个对象调用的hashCode方法计算的哈希码值一致导致计算机的数组索引值相同

HashMap底层数据结构

JDK1.8之前,HashMap是由数组+链表组成的,数组是HashMap主体,链表用来解决哈希冲突。即,发生hash冲突后使用equals判断是否相等,相等则存储在该节点的链表中。

JDK1.8之后,当链表长度大于阈值(或者红黑树的边界值,默认为8),并且当前数组长度大于64时,此时索引位置上的所有数据改为红黑树存储。

创建对象底层原理:

HashMap<String,Integer> map = new HashMap<>();
  1. 当创建HashMap集合对象时,

    • 在JDK8前,构造方法中创建一个长度是16的Entry[] table 用来存储键值对数据的

    • 在JDK8后,不是在HashMap的构造方法底层创建数组了,而是在第一次使用put方法时,创建的数组,Node[] table用来存储键值对数据的

  2. 存储数据数组位置为空时:

    • 比如将一个键值对 (“Benaso” ,1) 存储到哈希表中,根据 “Benaso” 调用 String 类中重写之后的hashCode() 方法计算出值,然后结合数组的长度采用某种算法算出向Node数组中存储数据的空间值索引,如果该索引对应空间没有数据,则将 (“Benaso” ,1) 存储到数组中

    • 面试题:哈希表底层采用何种算法计算hash值?还有哪些算法可以计算出hash值?

      • 底层采用key的hashCode方法的值结合数组长度进行无符号右移(>>>)、按位异或(^),按位与(&)计算出索引。(异或:两个二进制值相同为0,不同为1)

      • 还可以采用平方取中法,取余数,伪随机数法

      • 哈希表采用方法原因是与其他方法相比该方法效率高

  3. 存储数据数组位置不为空时:

    • 例如向hash表新存一组数据(“Victor” ,1),假设根据Victor计算出的hashCode方法结合数组长度计算出的索引值也是3,那么此时数组空间不是null,此时则会比较Victor的hash值是否一致,如果不一致,则在此空间上划出一个节点来存储键值对数据 (“Victor” ,1)。——这种方法被称为拉链法

  4. 假设向哈希表中存储数据 (“Benaso” ,2) 那么根据Benaso调用hashCode方法结合数组长度计算出索引也为3,此时对比较后存储的数据Benaso和已经存在的Benaso的hash值是否相等,如果相等,发生hash碰撞:

    • 相等:则将后添加的数据的value覆盖到其上

    • 不相等:那么继续向下和其它数据的key进行比较,如果都不相等,则划出一个节点存储数据。

  5. 一般不会等到存储数据到达16才扩容,

    threshold(临界值)= capacity(容量) * loadFactor(加载因子)

    这个值是当前已占用数组长度的最大值,size超过这个临界值就重新resize(扩容),扩容后的 HashMap 容量是之前容量的两倍。

HashMap集合类的成员

成员变量

集合的初始化容量(必须是二的n次幂

//默认初始容量是16 -- 1<<4相当于1*2的4次方 --- 1*16
static final int DEFAULT_INITAL_CAPACITY = 1 << 4

HashMap扩容

扩容条件

  1. 元素个数超过12扩容,

  2. 链表节点大于8,数组长度小于64

扩容后索引要么是原索引,要么是原索引加16

  • 计算新的索引高位是0那么存储到原来索引位置

  • 如果高位是1那么存储到原来索引加旧的数组的长度

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/165369.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

WordPress站点屏蔽过滤垃圾评论教程(Akismet反垃圾评论插件)

前段时间我的WordPress站点经常收到垃圾评论的轰炸&#xff0c;严重时一天会收到几十条垃圾评论。我这个小破站一没啥流量&#xff0c;二又不盈利&#xff0c;实在是不太理解为啥有人要这么执着地浪费资源在上面。 Akismet反垃圾评论插件 其实用了 Akismet 反垃圾评论插件后&a…

ARCore:在Android上构建令人惊叹的增强现实体验

ARCore&#xff1a;在Android上构建令人惊叹的增强现实体验 一、 AR 介绍1.1 AR技术简介1.2 AR技术原理1.3 AR技术应用领域 二、Google的增强现实平台ARCore2.1 ARCore简介2.2 ARCore API介绍2.3 ARCore API使用示例 三、总结 一、 AR 介绍 增强现实 Augmented Reality&#x…

An issue was found when checking AAR metadata

一、报错信息 An issue was found when checking AAR metadata:1. Dependency androidx.activity:activity:1.8.0 requires libraries and applications that depend on it to compile against version 34 or later of the Android APIs.:app is currently compiled against …

关于elementui和ant design vue无法禁止浏览器自动填充问题

以and design vue 为例&#xff1a; 图标用来显隐账号密码 html&#xff1a; <a-form-model-item label"账号密码:" prop"password"><a-input v-if"passwordTab" ref"passwordInput" v-model"form.password" typ…

详解最长公共子序列问题(三种方法)

这里&#xff0c;为了更方便地解释&#xff0c;我以洛谷上的一道典型题目为例&#xff0c;为大家讲解处理最长公共子序列问题的几种常见方法。这道题目中规定了两个子序列的长度相等&#xff0c;如果遇到不等的情况&#xff0c;也只需要对长度稍作修改即可&#xff0c;算法思想…

qs-一个序列化和反序列化的JavaScript库

起因 一个业务场景中&#xff0c;最终得到一串字符"status[0]value1&status[1]value2" 通过解析&#xff0c;理应得到一个数组&#xff0c;却得到一个对象 于是展开问题排查 最终发现是qs.parse 这个地方出了问题 排查结果 qs解析这种带下标的字符串时&#xff…

【Java 进阶篇】Redis 命令操作:轻松掌握基本操作

Redis是一款高性能的键值对存储系统&#xff0c;以其快速、灵活的特性而备受开发者推崇。本文将详细介绍Redis的基本命令操作&#xff0c;包括键值操作、数据查询、事务处理等方面&#xff0c;帮助初学者更好地理解和使用Redis。 基本命令 1. 键值操作 1.1 SET&#xff1a;设…

spark shuffle 剖析

ShuffleExchangeExec private lazy val writeMetrics SQLShuffleWriteMetricsReporter.createShuffleWriteMetrics(sparkContext)private[sql] lazy val readMetrics SQLShuffleReadMetricsReporter.createShuffleReadMetrics(sparkContext)用在了两个地方&#xff0c;承接的是…

【Flink】Standalone运行模式

独立模式是独立运行的&#xff0c;不依赖任何外部的资源管理平台&#xff1b;当然独立也是有代价的&#xff1a;如果资源不足&#xff0c;或者出现故障&#xff0c;没有自动扩展或重分配资源的保证&#xff0c;必须手动处理。所以独立模式一般只用在开发测试或作业非常少的场景…

Ps:参考线

参考线 Guides用于帮助精确地定位图像或元素&#xff0c;显示为浮动在图像上的非打印线&#xff0c;可以移动或移除&#xff0c;还可以临时锁定。 Ps 中的参考线可分为三大类&#xff1a;画布参考线、画板参考线和智能参考线。 可在“首选项/参考线、网格和切片”中设置参考线的…

深信服防火墙路由模式开局部署-手把手教学(小白篇)

PS&#xff1a;深信服的设备只有400能够通过console连接&#xff0c;一般用户是无法连接的&#xff0c;所以大家不要妄想着从Console连接设备了&#xff0c;开局就通过MANAGE进入Web就可以 接通电源后&#xff0c;开机拿一根网线&#xff0c;一端连接防火墙的MANAGE口&#xf…

【C++】泛型编程 ⑭ ( 类模板示例 - 数组类模板 | 容器思想 | 自定义类可拷贝 - 深拷贝与浅拷贝 | 自定义类可打印 - 左移运算符重载 )

文章目录 一、容器思想1、自定义类可拷贝 - 深拷贝与浅拷贝2、自定义类可拷贝 - 代码示例3、自定义类可打印 - 左移运算符重载 二、代码示例1、Array.h 头文件2、Array.cpp 代码文件3、Test.cpp 主函数代码文件4、执行结果 一、容器思想 1、自定义类可拷贝 - 深拷贝与浅拷贝 上…

大模型生态新篇章:以AI Agent为引,助企业创新应用落地

文 | 智能相对论 作者 | 沈浪 以聊天机器人、虚拟助手、智能客服等为代表的对话式人工智能 (Conversational AI Agents ) 在具体服务场景中的应用已经十分普遍。今年以来&#xff0c;随着大模型技术的爆发与加持&#xff0c;对话式AI被市场赋予了更高的期望。 “所有行业都值…

微服务实战系列之Feign

前言 不知不觉&#xff0c;“微服务实战系列”已完成了六篇&#xff0c;每篇都聚焦一个主题&#xff0c;目的是便于各位盆友能够快速、全面地接收和消化。 博主从服务注册到服务监控&#xff0c;从服务路由到服务安全&#xff0c;从身份认证到加密技术均有涉猎。凡此均有关微服…

Java核心知识点整理大全10-笔记

往期快速传送门&#xff1a; Java核心知识点整理大全-笔记_希斯奎的博客-CSDN博客文章浏览阅读9w次&#xff0c;点赞7次&#xff0c;收藏7次。Java核心知识点整理大全https://blog.csdn.net/lzy302810/article/details/132202699?spm1001.2014.3001.5501 Java核心知识点整理…

【LeetCode刷题】--67.二进制求和

67.二进制求和 方法&#xff1a;模拟计算 class Solution {public String addBinary(String a, String b) {StringBuilder ans new StringBuilder();int carry 0;for(int ia.length()-1,jb.length()-1;i>0||j>0;i--,j--){int sum carry;sum i >0 ? a.charAt(i) …

web:[WUSTCTF2020]朴实无华

题目 点开页面显示如下 页面显示了一行报错&#xff1a;Cannot modify header information - headers already sent by (output started at /var/www/html/index.php:3) in /var/www/html/index.php on line 4 意思为不能修改报头信息-报头已经发送(输出开始于/var/www/html/i…

MySQL与Redis如何保证数据的一致性

文章目录 MySQL与Redis如何保证数据的一致性&#xff1f;不好的方案1. 先写 MySQL&#xff0c;再写 Redis2. 先写 Redis&#xff0c;再写 MySQL3. 先删除 Redis&#xff0c;再写 MySQL 好的方案4. 先删除 Redis&#xff0c;再写 MySQL&#xff0c;再删除 Redis5. 先写 MySQL&am…

Leetcode算法系列| 1. 两数之和(四种解法)

目录 1.题目2.题解解法一&#xff1a;暴力枚举解法二&#xff1a;哈希表解法解法三&#xff1a;双指针(有序状态)解法四&#xff1a;二分查找(有序状态) 1.题目 给定一个整数数组 nums 和一个整数目标值 target&#xff0c;请你在该数组中找出 和为目标值 target 的那 两个 整数…

『RabbitMQ』入门指南(安装,配置,应用)

前言 RabbitMQ 是在 AMQP&#xff08;Advanced Message Queuing Protocol&#xff09; 协议标准基础上完整的&#xff0c;可复用的企业消息系统。它遵循 Mozilla Public License 开源协议&#xff0c;采用 Erlang 实现的工业级的消息队列(MQ)服务器&#xff0c;建立在 Erlang …