由红黑树引出的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那么存储到原来索引加旧的数组的长度

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

node与 pnpm、node-sass 等工具的版本兼容关系

1. node & pnpm 2. node & node-sass 3. node-sass & sass-loader sass-loader依赖于node-sass&#xff0c;以下是部分版本号对应

ES 万条以外分页检索功能实现及注意事项

背景 以 ES 存储日志&#xff0c;且需要对日志进行分页检索&#xff0c;当数据量过大时&#xff0c;就面临 ES 万条以外的数据检索问题&#xff0c;如何利用滚动检索实现这个需求呢&#xff1f;本文介绍 ES 分页检索万条以外的数据实现方法及注意事项。 需求分析 用 ES 存储数…

GPU服务器常见故障修复记录

日常写代码写方案文档&#xff0c;偶尔遇上服务器出现问题的时候&#xff0c;也需要充当一把运维工程师&#xff0c;此帖用来记录GPU服务器报错的一些解决方案&#xff0c;仅供参考&#xff01; 文章目录 一、服务器简介二、机箱拆解三、基本操作四、常见故障4.1 电源开关键闪烁…

HBuilderX前端软件社区+Thinkphp后端源码

HBuilderX前端软件社区thinkphp后端源码&#xff0c;搭建好后台在前端找到 util 这个文件把两个js文件上面的填上自己的域名&#xff0c;登录HBuilderX账号没有账号就注册账号然后上传文件即可。打包选择发行 可以打包app或h5等等 后端设置运行目录为public(重要)&#xff0c;…

解决:ImportError: cannot import name ‘Adam‘ from ‘keras.optimizers‘

解决&#xff1a;ImportError: cannot import name ‘Adam‘ from ‘keras.optimizers‘ 背景 在使用之前的代码时&#xff0c;报错&#xff1a; from keras.optimizers import Adam ImportError: cannot import name ‘Adam’ 报错问题 from keras.optimizers import Adam I…

Unity调用dll踩坑记

请用写一段代码&#xff0c;让unity无声无息的崩溃。 你说这怕是有点难哦&#xff0c;谁会这么不幸呢&#xff1f;不幸的是&#xff0c;我幸运的成为了那个不幸的人。 unity里面调用dll的方式是使用 DllImport &#xff0c;比如有一个 Hello.dll&#xff0c;里面有一个 char* …

计算机网络之应用层

一、概述 引入目的&#xff1a; 为了方便用户去使用&#xff1b; 该如何方便用户使用网络呢&#xff0c;即怎样帮助用户使用网络&#xff1f; 1.用户需要知道网络资源所在的位置 2.网络上资源一定是在资源子网的主机上 3.资源子网上的主机&#xff0c;在通信子网中用IP地…

Android设计模式--装饰模式

千淘万漉虽辛苦&#xff0c;吹尽黄沙始到金 一&#xff0c;定义 动态地给一个对象添加一些额外的职责。就增加功能来说&#xff0c;装饰模式相比生成子类更为灵活。 装饰模式也叫包装模式&#xff0c;结构型设计模式之一&#xff0c;其使用一种对客户端透明的方式来动态地扩展…

基于SpringBoot+Vue的电子产品销售管理系统

基于SpringBootVue的电子产品销售管理系统的设计与实现~ 开发语言&#xff1a;Java数据库&#xff1a;MySQL技术&#xff1a;SpringBootMyBatisVue工具&#xff1a;IDEA/Ecilpse、Navicat、Maven 系统展示 主页 购物车 管理员界面 摘要 基于Spring Boot和Vue的电子产品销售管…

如何开启MySQL的慢查询日志

说明&#xff1a;如果需要查看某一条SQL查询速度慢&#xff0c;并对慢的SQL进行优化&#xff0c;那么开启MySQL慢查询日志是一定要做的事情&#xff0c;本文介绍如何开启MySQL的慢查询日志&#xff1b; 查看MySQL慢查询是否开启 首先&#xff0c;输入下面的命令&#xff0c;查…

再添千万级罚单,某银行年内罚款过亿!金融行业合规问题亟待解决

11月17日晚间&#xff0c;国家金融监管总局上海监管局披露行政处罚信息显示&#xff0c;某银行因32项违法违规事实收到两张690万元的大额罚单&#xff0c;合计罚款金额达1380万元。但这并不是银行该今年收到的第一张大额罚单。今年4月28日&#xff0c;该行因在结售汇、外币理财…

Okhttp 浅析

安全的连接 OkHttpClient: OkHttpClient: 1.线程调度 2.连接池,有则复用,没有就创建 3.interceptor 4.interceptor 5.监听工厂 6.是否失败重试 7.自动修正访问,如果没有权限或认证 8是否重定向 followRedirects 9.协议切换时候是否继续重定向 10.Cookie jar 容器 默认…

Electron+VUE3开发简版的编辑器【文件预览】

简版编辑器的功能主要是: 打开对话框,选择文件后台读取文件文件前端展示文件内容。主要技术栈是VUE3、Electron和Nodejs,VUE3做页面交互,Electron提供一个可执行Nodejs的环境以及支撑整个应用的环境,nodeJS负责读取文件内容。 环境配置、安装依赖这些步骤就不再叙述了。 …

PHP众筹系统源码+支持报名众筹+商品众筹+无偿众筹+市面上所有的众筹模式 附带完整的搭建教程

大家好啊&#xff0c;罗峰今天来给大家分好用的源码系统了。今天要给大家分享的是一款PHP众筹系统源码。众筹作为一种新型的融资方式&#xff0c;逐渐在市场上占据了重要的地位。从公益众筹到商品众筹&#xff0c;再到股权众筹&#xff0c;各种众筹模式层出不穷。然而&#xff…

Go lumberjack 日志轮换和管理

在开发应用程序时&#xff0c;记录日志是一项关键的任务&#xff0c;以便在应用程序运行时追踪问题、监视性能和保留审计记录。Go 语言提供了灵活且强大的日志记录功能&#xff0c;可以通过多种方式配置和使用。其中一个常用的日志记录库是 github.com/natefinch/lumberjack&am…

Proteus下仿真AT89C51报“串行口通信失败,请检查电平适配是否正确。”解决办法

在Proteus下进行AT89C51串行口仿真时&#xff0c;如果遇到“串行口通信失败&#xff0c;请检查电平适配是否正确”的错误提示&#xff0c;以下是一些解决办法&#xff1a; 1. 了解AT89C51和外部设备的电平要求&#xff1a; 首先&#xff0c;了解AT89C51和外部设备之间的电平…

【数据结构(C语言)】浅谈栈和队列

目录 文章目录 前言 一、栈 1.1 栈的概念及结构 1.2 栈的实现 1.2.1. 支持动态增长的栈的结构 1.2.2 初始化栈 1.2.3 入栈 1.2.4 出栈 1.2.5 获取栈顶元素 1.2.6 获取栈中有效元素个数 1.2.7 检查栈是否为空 1.2.8 销毁栈 二、队列 2.1 队列的概念及结构 2.2 队…

[BJDCTF2020]The mystery of ip1

提示 ssti模板注入head头x-forwarded-for 每一次做题的最开始流程都大致因该是 信息收集找可以操控的地方 查看hint页面的源代码又发现它提示说 ####你知道为什么会知道你的ip吗 查看flag页面 从刚才给我的提示以及他这里显示的我的ip&#xff0c;大概找到了我可操作的可控点 …

Spark---基于Yarn模式提交任务

Yarn模式两种提交任务方式 一、yarn-client提交任务方式 1、提交命令 ./spark-submit --master yarn --class org.apache.spark.examples.SparkPi ../examples/jars/spark-examples_2.11-2.3.1.jar 100 或者 ./spark-submit --master yarn–client --class org.apache.s…

学习.NET验证模块FluentValidation的基本用法(续1:其它常见用法)

FluentValidation模块支持链式验证方法调用&#xff0c;也就是说&#xff0c;除了 RuleFor(r > r.UserName).NotEmpty()调用方式之外&#xff0c;还可以将对单个属性的多种验证函数以链式调用方式串接起来&#xff0c;比如UserName属性不能为空&#xff0c;长度在5~10之间&a…