当前位置: 首页 > 编程日记 > 正文

hashMap传入参数,table长度为多少

前言


我的所有文章同步更新与Github--Java-Notes,想了解JVM,HashMap源码分析,spring相关,剑指offer题解(Java版),可以点个star。可以看我的github主页,每天都在更新哟。

邀请您跟我一同完成 repo


创建函数时,传入初始长度0,1,2,3,4……15,16,数组table长度为多少

记住一点,当table进行初始化的时候,table.length 就是 比传入的值大的或者等于的最小的 2的n次方table.length 的长度一直是 2的n次方

也就是说,我new HashMap(0),table初始化后 table.length ==1(当然,源码中所有的变量都采用延迟初始化,只有等到用的时候,即put元素的时候才初始化。如果没有放入元素,那么 table一直为 null,我上面的只是另外一个变量 threshold得出来的,因为这两个有关系。我使用断点调试一下就知道了)

我们注意到,当构建函数时,threshold的初始值和 tableSizeFor()这个函数有关

我们再进入tableSizeFor

这个是返回一个比输入值大的或者等于的最小的 2的n次方(如果你不明白可以看下我后面的测试值和这篇文章

www.cnblogs.com/loading4/p/…

所以他返回的值为 1(比0大的或者等于的最小的2的n次方 就是1);

然后这个时候假如我们第一次 put一个元素,这个时候table数组就要开始初始化了,他就会执行这个resize函数,在源码中是这样

resize的解读如下

/*** 扩容函数*   使用情景: 1.初始化数组table,*           2.++size>threshold. * @return 新的数组table*         或者是当扩容一倍长度超过最大值,返回原来的table数组*/final  Entry[] resize() {// 定义旧的数组为 Entry 类型的数组,oldTabEntry[] oldTab = table;// 如果oldTab==null  则返回 0,否则返回数组大小int oldCap = (oldTab==null) ? 0 : oldTab.length;int oldThreshold = threshold;int newCap,newThreshold=0;// 说明已经不是第一次 扩容,那么已经初始化过,容量一定是 2的n次方,所以可以直接位运算if(oldCap>0){// 如果 原来的数组大小已经大于等于了最大值,那么阈值设置为 Integer的最大值,即不会再进行扩容if(oldCap >= MAX_CAPACITY){threshold = Integer.MAX_VALUE;return oldTab;}// 因此已经不是第一次扩容,一定是2的n次方else if ((newCap = oldCap << 1) < MAX_CAPACITY &&oldCap >= INIT_CAPACITY)newThreshold = oldThreshold << 1;}// 如果oldThreshold > 0,并且oldCap == 0,说明是还没有进行调用resize方法。// 说明输入了初始值,且oldThreshold为 比输入值大的最小的2的n次方// 那么就把 oldThreshold 的值赋给 newCap ,因为这个值现在为 比输入值大的最小的2的n次方else if(oldThreshold>0)newCap = oldThreshold;// 这个是只有使用无参构造器的时候才能满足的条件。,全部是否默认的值else{newCap = INIT_CAPACITY;newThreshold = (int) (INIT_CAPACITY * DEFAULT_LOADFACTOR);}//if(newThreshold == 0){float ft = (float) (newCap * loadFactor);newThreshold =(newCap < MAX_CAPACITY && ft < (float) MAX_CAPACITY ?(int )ft : Integer.MAX_VALUE);}threshold = newThreshold;Entry newTable[] = new Entry[newCap];table=newTable;// 将原来数组中的所有元素都 copy进新的数组if(oldTab != null){for (int j = 0; j < oldCap; j++) {Entry e;if((e = oldTab[j]) != null){oldTab[j] = null;// 说明还没有成链,数组上只有一个if(e.next == null){// 重新计算 数组索引 值newTable[e.h & (newCap-1)] = e;}// 判断是否为树结构//else if (e instanceof TreeNode)// 如果不是树,只是链表,即长度还没有大于 8 进化成树else{// 扩容后,如果元素的 index 还是原来的。就使用这个lo前缀的Entry loHead=null, loTail =null;// 扩容后  元素index改变,那么就使用 hi前缀开头的Entry hiHead = null, hiTail = null;Entry next;do {next = e.next;//这个非常重要,也比较难懂,// 将它和原来的长度进行相与,就是判断他的原来的hash的上一个	bit 位是否为 1。//以此来判断他是在相同的索引还是table长度加上原来的索引if((e.h & oldCap) == 0){// 如果 loTail == null ,说明这个 位置上是第一次添加,没有哈希冲突if(loTail == null)loHead = e;elseloTail.next = e;loTail = e;}else{if(hiTail == null)loHead = e;elsehiTail.next = e;hiTail = e ;}}while ((e = next) != null);if(loTail != null){loTail.next = null;newTable[j] = loHead;}// 新的index 等于原来的 index+oldCapelse {hiTail.next = null;newTable[j+oldCap] = hiHead;}}}}}return newTable;}复制代码

我们注意这里,满足这个的条件为 oldCap==0 && oldThreshold>0

    else if(oldThreshold>0)newCap = oldThreshold;
复制代码

oldThreshold等于之前使用 tableSizeFor 的返回值,也就是 1;所以table一经初始化长度就为1**(但是还要说明一点,执行完 resize函数之后 table.length等于1,threshold等于0。看我上面的分析,newThreshold=(int)0.75)就等于0**

但是我们执行的是存入元素的操作,所以存完之后,就要++size(因为之前里面没有元素),这个时候 size就等于1,他就大于 threshold。所以他又要执行resize函数进行扩容操作。执行完之后,table.length 就等于2了,threshold就等于 1了。

table的扩容全部都是乘以 2(左移一位),而且table.length也一直等于2的n次方,即(table.length &(table.length-1)) == 0

之后同理可以推,一开始创建对象时,传入 1的话,table 初始化长度为1;传入 2,长度为2;传入3,长度为4;传入[5,8],长度为8;传入[9,16],长度为16

转载于:https://juejin.im/post/5ca720bdf265da30bb58102c

相关文章:

【OpenCV】图像/视频相似度测量PSNR( Peak signal-to-noise ratio) and SSIM,视频/图片转换

目录 1 目标 2 原理 2.1 图像比较 - PSNR and SSIM 3 代码 3.1如何读取一个视频流&#xff08;摄像头或者视频文件)&#xff1f; 3 运行效果 视频/图片转换&#xff1a; 如何用OpenCV创建一个视频文件用OpenCV能创建什么样的视频文件如何释放视频文件当中的某个颜色通道…

struts2提交list

2019独角兽企业重金招聘Python工程师标准>>> Action: private List<User> users; jsp: <input type"text" name"users[0].name" value"aaa" /> <input type"text" name"users[1].name" value&q…

双阈值法的实现

#include "opencv2/imgproc/imgproc.hpp" #include "opencv2/highgui/highgui.hpp" int main( ) {// 图像读取及判断cv::Mat srcImage cv::imread("..\\images\\hand1.jpg");if( !srcImage.data ) return 1;// 灰度转换cv::Mat srcGray;cv::cvt…

设计模式 小记

观察者模式 1.被观察者是单例模式。 生成这模式 1.Director中对于Builder的引用不一定是Strong&#xff0c;根据情况也有可能是Copy。 2.Director 聚合 Builder&#xff0c; 所以Builder本身可以单独拿出来使用。 转载于:https://juejin.im/post/5ca8c24df265da3094116c18

【MATLAB】————matlab raw图转bmp实现

image_path [layer_3_list_folder,\,layer_3_list_name]; img_raw_path fopen(image_path,r);%%打开图像 img_raw fread(img_raw_path,[Width,Height],uint16);% uchar为无符号字符型 mg_raw uint8(img_raw);%%unit8表示无符号整数&#xff0c;范围0-255&#xff0c;u…

人工手动冷备不完全恢复介绍(purge表不完全恢复)

不完全恢复不完全恢复的基本类型&#xff1a;1&#xff09;基于时间点 &#xff08;until time): 使整个数据库恢复到过去的一个时间点前2&#xff09;基于scn &#xff08;until change&#xff09;&#xff1a; 使整个数据库恢复到过去的某个SCN前3&#xff09;基于cancel (u…

半阈值法的实现

#include "opencv2/imgproc/imgproc.hpp" #include "opencv2/highgui/highgui.hpp" #include <iostream> using namespace std; using namespace cv; int main( ) {// 读取源图像及判断cv::Mat srcImage cv::imread("..\\images\\hand1.jpg&q…

novaclient的api调用流程与开发

novaclient的api调用流程与开发 2015年07月05日 19:27:17 qiushanjushi 阅读数&#xff1a;3915 http://blog.csdn.net/tpiperatgod/article/details/18375387?utm_sourcetuicool 另一个地址&#xff1a;http://neuromancer.sinaapp.com/?p64 从nova client的入口查看 cat /u…

【C++】 保存内容到文件工具

1. c 输出到文件 // save mean distance between center and descriptorsstd::string filename configuration_.debug_output_path() "ref_max_mean_distance.txt";FILE* fp fopen(filename.c_str(), "w");try {if (fp nullptr) {return error::Failed…

你知道实习对你有多重要吗?

大学生就业一直是个永恒不变的话题&#xff0c;在过去几年中&#xff0c;每​‌‌次临近毕业季&#xff0c;我们肯定会一次次的听到“史上最难就业季”之说。而每一年的数据也会不断突破前一年的数字。在国新办举行的新闻发布会上&#xff0c;人力资源社会保障部部长尹蔚民提到…

灰度直方图的实现

#include <opencv2\opencv.hpp> int main() {// 图像源获取及判断 cv::Mat Image, ImageGray;Image cv::imread("..\\images\\flower3.jpg"); if(Image.empty()) return -1;cv::imshow("Image",Image);// 转换为灰度图像cv::cvtColor(Image,Image…

Android笔记之ViewModel的使用示例

依赖 implementation android.arch.lifecycle:extensions:1.1.1 implementation com.squareup.retrofit2:retrofit:2.5.0 implementation com.squareup.retrofit2:converter-gson:2.5.0 implementation com.squareup.retrofit2:adapter-rxjava2:2.5.0 implementation io.reacti…

vscode配置记录

vscode配置记录 按照官网教程安装好vs:实际上只需要配置launch.json的”program“如下所示 "configurations": [{"name": "(gdb) Launch","type": "cppdbg","request": "launch","program":…

unity 2d 游戏优化之路 遇坑记录

情景说明&#xff1a; unity 出的Android包&#xff0c;在目前一些主流机型跑都没有问题&#xff0c;但是在 小米3 这种比较老的机器上跑&#xff0c;报如下错误 GLSL compilation failed, no infolog provided 起先&#xff0c;我们一直以为是在低端机器上某个特定的GLSL 在这…

自定义直方图实现

#include <opencv2/opencv.hpp> int main() {// 图像获取及判断cv::Mat srcImage cv::imread("..\\images\\flower3.jpg");if( !srcImage.data ) return 1;cv::imshow("srcImage",srcImage);// 灰度转换 cv::Mat srcGray;cv::cvtColor(srcImage,sr…

js数组指定位置添加删除

示例参考&#xff1a;http://www.w3school.com.cn/jsref/jsref_splice.asp转载于:https://www.cnblogs.com/CarryYou-lky/p/10669859.html

【C++】对象实例化/成员函数/成员变量的内存管理

文章目录1. 对象实例化的内存管理总结2.C成员函数在内存中的存储方式3.C类的实例化对象的大小之sizeof()实例一&#xff1a;实例二&#xff1a;实例三&#xff1a;实例四&#xff1a;实例五&#xff1a;实例六&#xff1a;实例七&#xff1a;实例八&#xff1a;实例九&#xff…

HTML form 标签的 enctype 属性

1. enctype 的定义和用法 enctype 属性规定在发送到服务器之前应该如何对表单数据进行编码。 默认地&#xff0c;表单数据会编码为 "application/x-www-form-urlencoded"。 就是说&#xff0c;在发送到服务器之前&#xff0c;所有字符都会进行编码&#xff08;空格转…

灰度直方图均衡化实现

#include <opencv2/opencv.hpp> int main() {cv::Mat srcImage cv::imread("..\\images\\flower3.jpg");if( !srcImage.data ) return 1;cv::Mat srcGray;cv::cvtColor(srcImage, srcGray, CV_BGR2GRAY);cv::imshow("srcGray", srcGray);// 直方图均…

oracle汉化包下载地址

2019独角兽企业重金招聘Python工程师标准>>> https://www.allroundautomations.com/bodyplsqldevreg.html 转载于:https://my.oschina.net/u/3141521/blog/3034655

【C++】C/C++ 中 static 的用法全局变量与局部变量

C/C 中 static 的用法全局变量与局部变量 目录 1. 什么是static? 1.1 static 的引入 1.2 静态数据的存储 2. 在 C/C 中static的作用 2.1 总的来说 2.2 静态变量与普通变量 2.3 静态局部变量有以下特点&#xff1a; 实例 3. static 用法 3.1 在 C 中 3.2 静态类相关…

浅谈C/C++中的static和extern关键字

一.C语言中的static关键字 在C语言中&#xff0c;static可以用来修饰局部变量&#xff0c;全局变量以及函数。在不同的情况下static的作用不尽相同。 (1)修饰局部变量 一般情况下&#xff0c;对于局部变量是存放在栈区的&#xff0c;并且局部变量的生命周期在该语句块执行结束时…

彩色直方图均衡化实现

#include <opencv2/opencv.hpp> int main() {// 图像获取及验证cv::Mat srcImage cv::imread("..\\images\\flower3.jpg");if( !srcImage.data ) return 1;// 存储彩色直方图及图像通道向量cv::Mat colorHeqImage; std::vector<cv::Mat> BGR_plane; …

二、python小功能记录——监听鼠标事件

1.原文链接 #-*- coding:utf-8 -*- from pynput.mouse import Button, Controller## ## 控制鼠标 ## # 读鼠标坐标 mouse Controller() print(The current pointer position is {0}.format(mouse.position)) # 设置鼠标坐标 mouse.position (10, 20) print(No…

【Smart_Point】C/C++ 中智能指针

C11智能指针 目录 C11智能指针 1.1 C11智能指针介绍 1.2 为什么要使用智能指针 1.2.1 auto_ptr&#xff08;C98的方案&#xff0c;C11已经抛弃&#xff09;采用所有权模式。 1.2.2 unique_ptr 1.2.3 shared_ptr 1.2.4 weak_ptr 1.3 share_ptr和weak_ptr的核心实现 1.…

Linux 虚拟内存和物理内存的理解【转】

转自:http://www.cnblogs.com/dyllove98/archive/2013/06/12/3132940.html 首先&#xff0c;让我们看下虚拟内存&#xff1a; 第一层理解 1. 每个进程都有自己独立的4G内存空间&#xff0c;各个进程的内存空间具有类似的结构 2. 一个新进程建立的时候&#xff0c…

直方图变换——查找

#include <opencv2/core/core.hpp> #include <opencv2/imgproc/imgproc.hpp> #include <opencv2/highgui/highgui.hpp> int main() {// 图像获取及验证cv::Mat srcImage cv::imread("..\\images\\flower3.jpg");if( !srcImage.data ) return 1;//…

【C++】C/C++ 中default/delete特性

C类的特殊成员函数及default/delete特性 本文内容侧重个人理解&#xff0c;深入理解其原理推荐https://www.geeksforgeeks.org 目录 目录 C类的特殊成员函数及default/delete特性 前言 1. 构造函数和拷贝构造函数 2. 拷贝赋值运算符 3. C11特性之default关键字(P237, P4…

Celery--任务调度利器

2019独角兽企业重金招聘Python工程师标准>>> Celery文档: http://docs.jinkan.org/docs/celery/getting-started/first-steps-with-celery.html 安装celery和celery-with-redis pip install Celery pip install celery-with-redis开始编写task.py # tasks.py import…

直方图变换——累计

#include <opencv2/core/core.hpp> #include <opencv2/imgproc/imgproc.hpp> #include <opencv2/highgui/highgui.hpp> int main() {// 图像获取及验证cv::Mat srcImage cv::imread("..\\images\\flower3.jpg");if( !srcImage.data ) return 1;//…