【Java集合】聊聊Hashmap的哈希函数、扩容、树化

哈希函数

hashmap是开发中常用的一个集合,除了一些基本的属性、put、get等流程,本篇文章主要介绍下哈希函数、扩容、树化的一些细节。
而hash函数就是hashmap的重中之重。

    static final int hash(Object key) {int h;return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);}int index = hash(key) & (n - 1)

从上述的code中,可以看出hash的整体流程,就是获取key的hashcode值给h,然后h 进行右移 16位,在进行异或操作(相同为0,不同为1),因为计算的hashcode值比较大,所以需要在对 数组(n-1) 进行取对应的下表,取模操作比较耗时,所以才使用位运算。

在这里插入图片描述
为什么不直接使用 hashcode直接返回?
那么既然key的hashcode是一个随机数,为什么不直接返回呢,而是要进行 异或操作 h ^ (h >>> 16) ,因为一般来说hashmap的长度不会很长,如果直接返回,高位其实没有参与到运算中,会导致计算出的不够均匀。

**为什么 h& (n - 1) **
hashmap中table数组的大小是2的幂次方。比如 2^4 减1之后 其实就是 1111 跟h& 相当于求模运算。

扩容机制

当我们存储数据的使用,一般除非特别指定会设置一定的容量,否则,当添加的元素超过一定的阈值就会进行扩容,有扩容就对应有缩容。

装载因子

具体扩容是根据table数组的大小和 装载因子决定的, 当元素个数超过 n * loadFactor 就会触发扩容。
lodFactory 默认是0.75 ,table数组默认大小是16。当元素超过12之后就会触发扩容。

    public HashMap(int initialCapacity, float loadFactor) {if (initialCapacity < 0)throw new IllegalArgumentException("Illegal initial capacity: " +initialCapacity);if (initialCapacity > MAXIMUM_CAPACITY)initialCapacity = MAXIMUM_CAPACITY;if (loadFactor <= 0 || Float.isNaN(loadFactor))throw new IllegalArgumentException("Illegal load factor: " +loadFactor);this.loadFactor = loadFactor;this.threshold = tableSizeFor(initialCapacity);}
/*** Returns a power of two size for the given target capacity.*/static final int tableSizeFor(int cap) {int n = cap - 1;n |= n >>> 1;n |= n >>> 2;n |= n >>> 4;n |= n >>> 8;n |= n >>> 16;return (n < 0) ? 1 : (n >= MAXIMUM_CAPACITY) ? MAXIMUM_CAPACITY : n + 1;}

从上述的源码中,可以看到其实在设置指定长度的时候,其实就按照2的次幂进行分配。如果不是的化,那么tableSizeFor就会转换比initialCapacity大的第一个2的幂次方数。
在这里插入图片描述
this.threshold = tableSizeFor(initialCapacity);
细心的同学可能发现了,这个计算之后的容量是直接赋值给了threshold。而这个tableSizeFor(initialCapacity); 是数组的大小,threshold是触发扩容的阈值。
那是因为new hashMap的时候,并没有开始创建table数组,而是在put元素的时候,才会进行初始化。
在这里插入图片描述

默认装载因子

对于装载因子 为什么设置为0.75,可能有的面试官就纠结于此,询问这个问题,但是我们最好还是了解一下。
结论就是 0.75是结合时间和空间综合考虑的结果。过大,执行效率低。过小。浪费空间。

链表树化阈值

链表树化的阈值为什么是8,其实是根据泊松分布来计算的概率问题。
在这里插入图片描述

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

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

相关文章

阅读芯片源码(RTL)

part one 主要的原则。 一个rtl可以是这样的&#xff1a; 经常大家习惯于算法和数据结构。对于设计的部分&#xff0c;落实不一定多。 另外一个rtl也可以是这样的&#xff1a; 所以从不同的层面来讲&#xff0c;一个Rtl有不同的表述。 首先大概把所有的部分浏览一遍&#x…

CICD 持续集成与持续交付——gitlab

部署 虚拟机最小需求&#xff1a;4G内存 4核cpu 下载&#xff1a;https://mirrors.tuna.tsinghua.edu.cn/gitlab-ce/yum/el7/ 安装依赖性 [rootcicd1 ~]# yum install -y curl policycoreutils-python openssh-server perl[rootcicd1 ~]# yum install -y gitlab-ce-15.9.3-ce.0…

Jmeter——结合Allure展示测试报告

在平时用jmeter做测试时&#xff0c;生成报告的模板&#xff0c;不是特别好。大家应该也知道allure报告&#xff0c;页面美观。 先来看效果图&#xff0c;报告首页&#xff0c;如下所示&#xff1a; 报告详情信息&#xff0c;如下所示&#xff1a; 运行run.py文件&#xff0c;…

AVL树实现

目录 ​编辑 一&#xff0c;AVL树的概念 二&#xff0c;实现AVL树&#xff08;部分&#xff09; 1.AVL树的节点 2.AVL数的插入 1.当根节点为nullptr时要执行如下代码&#xff1a; 2.当根节点不为nullptr时 1.当parent的_bf变为0时&#xff0c;parent之前的_bf的大小就是…

前端面试:如何实现并发请求数量控制?

题目&#xff1a;实现一个并发请求函数concurrencyRequest(urls, maxNum) 要求如下&#xff1a; 要求最大并发数 maxNum;每当有一个请求返回&#xff0c;就留下一个空位&#xff0c;可以增加新的请求;所有请求完成后&#xff0c;结果按照 urls 里面的顺序依次打出&#xff1b;…

C++初阶-内存管理

内存管理 一、C/C内存分布二、C语言中动态内存管理方式&#xff1a;malloc/calloc/realloc/free三、C内存管理方式new/delete操作内置类型new和delete操作自定义类型 四、operator new与operator delete函数operator new与operator delete函数 五、new和delete的实现原理内置类…

论文-分布式-拜占庭将军问题

目录 0-前言 1-导引 2-不可能性 3将军(1叛徒)问题不存在解/不能达成共识 少于3m1个将军(有m个叛徒)不存在解/不能达成共识 精确一致性与近似一致性是同等困难的 3-使用口头消息的解 “口头消息”的含义 OM(m)算法的步骤 OM(m)算法的正确性推导 4-使用签名消息情况下…

054-第三代软件开发-信号槽

第三代软件开发-信号槽 文章目录 第三代软件开发-信号槽项目介绍信号槽实现原理与MFC消息映射机制区别Qt信号槽机制的优缺点 关键字&#xff1a; Qt、 Qml、 关键字3、 关键字4、 关键字5 项目介绍 欢迎来到我们的 QML & C 项目&#xff01;这个项目结合了 QML&#x…

内容运营策略:个性化推荐

一、推荐系统流程 典型的推荐系统包括3个部分&#xff0c;即召回层&#xff08; Recall )、排序层&#xff08; Rank )和重排层&#xff08; ReRank )。 1&#xff0e;召回层&#xff08; Recall ) 召回层主要是从全量库中首先获取用户可能感兴趣的候选集&#xff0c;是推荐系…

Pytest自动化测试框架:mark用法---测试用例分组执行

pytest中的mark&#xff1a; mark主要用于在测试用例/测试类中给用例打标记(只能使用已注册的标记名)&#xff0c;实现测试分组功能&#xff0c;并能和其它插件配合设置测试方法执行顺序等。 如下图&#xff0c;现在需要只执行红色部分的测试方法&#xff0c;其它方法不执行&am…

pytest测试框架介绍(1)

又来每天进步一点点啦~~~ 一、Pytest介绍&#xff1a; pytest 是一个非常成熟的全功能的Python测试框架&#xff1b; pytest 简单、灵活、易上手&#xff1b; 支持参数化 能够支持简单的单元测试和复杂的功能测试&#xff0c;可以做接口自动化测试&#xff08;pytestrequests&…

谈谈一个IT杂家的职业生涯规划,你的护城河被AI 攻破了么?

文章大纲 未来AI领域的专家是深度学习老中医数据为什么不断的在变化&#xff1f;炼金术(Alchemy)AI“老中医”的经验难以复制 AIGC 还未能克服的难点&#xff1a;忽然的惊喜与价值观对齐失控既是智能获得突破的重要原因&#xff0c;又是智能突破所不可避免的伴生结果大模型在泛…