HashMap常见问题(更新中)
HashMap
//JDK1.8以后的HashMap部分源码
static final int hash(Object key){
int h;
return (key == null)?0(h=key.hashCode())^(h>>>16);
}
hash算法的优化:
对每个hash值,将他的高低十六位进行异或操作,让低十六位同时保持了高低十六位的特征。同时也可以避免一些hash值后续出现冲突。
寻址算法的优化:
寻址算法就是对长度为n的数组取模,得到在数组中的位置。根据数学规律,对n取模,就是和n-1进行与运算。与运算的效率远远高于求模运算,所以采用与运算。而数组的长度通常没有很大,所以高位与出来都是0,如果不进行hash算法优化,那么高位的信息就会丢失。 综上就是JDK8的hash算法的优化。
03.HashMap是如何解决hash碰撞问题的?
hash冲突问题, 链表 + 红黑树 ,o(n)和o(logn) 当发生hash冲突时,会在数组中重复的位置放置一个链表,然后将value的值加入链表中。但是由于链表的查询时间复杂度是o(n),所以当链表的变的很长的时候,我们获取值会变的很慢。为了提升性能,当链表的长度到达一定值时,我们将链表转换成红黑树,红黑树的查询时间复杂度是o(logn),提升性能。
04.说说HashMap是如何进行扩容的?
hashMap底层默认是一个数组,当这个数组满了以后,就会自动扩容,变成一个更大的数组,可以在里面放更多的元素。 hashMap的默认大小是16位的,当16存满以后就会进行2倍扩容,变成长度为32的数组。这个时候就要对原先数组中存储的元素进行rehash,即将他们的哈希值和(32-1)进行与运算,原本在长度为16的处于相同位置的几个元素,可能就要变换位置,不在同样的位置了。 为什么进行两倍扩容? 两倍扩容就是二进制位的上一位变成1,比如 0000 0000 0000 1111 变成 0000 0000 0001 1111 在进行rehash操作时,判断二进制结果是否多了一个bit的1,如果没多,那么就是原来的index,如果多了,那么就是index + oldcap,通过这个方式,避免rehash的时候,进行取模运算,位运算的性能更高。 注意,我们最好在使用hashMap的时候能够指定合适的hashMap的大小,来避免扩容,这样就能避免rehash操作,影响性能。
- MVC 5 Scaffolder + EntityFramework+UnitOfWork Pattern 代码生成工具集成Visual Studio 2013
- 左手用R右手Python系列——百度地图API调用与地址解析/逆解析
- OpenCV实战:人脸关键点检测(FaceMark)
- Asp.Net MVC +EntityFramework主从表新增编辑操作的实现(删除操作怎么实现?)
- 模板模板模板模板模板模板模板模板模板模板模板模板模板模板模板模板模板模板模板模板
- 洛谷P1311 选择客栈
- 洛谷P1607 [USACO09FEB]庙会班车Fair Shuttle
- R语言抓包实战——知乎live二级页面获取
- 左手用R右手Python系列——面向对象编程基础
- 线性同余同余方程组解法(excrt)
- #19. 计数(容斥原理)
- 左手用R右手Python系列——多进程/线程数据抓取与网页请求
- #15. 钻石
- P1328 生活大爆炸版石头剪刀布
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- K8S的名称空间创建&&版本的升级、回滚操作
- SAP Cloud for Customer CLR(Code List Restriction)的一种高级用法
- SAP WebClient UI One Hit Navigation的实现方法
- 【打包构建】Mac下使用expect实现执行sudo命令时自动输入密码
- ASP.NET Core 奇淫技巧之SPA部署
- SAP Cloud for Customer Rule Editor的使用方法和底层工作原理
- (数据科学学习手札94)QGIS+Conda+jupyter玩转Python GIS
- 72-STM32+ESP8266+AIR202基本控制篇-移植使用-移植Android的MQTT包到自己的工程项目
- 用上Latex实现编辑伪代码
- TensorFlow交叉熵函数(cross_entropy)·理解
- 第05期:Prometheus 数据查询(一)
- 技术分享 | MySQL 复制那点事 - Seconds_behind_Master 参数调查笔记
- 线程有多少种状态?Runnable 一定在执行任务吗?
- swift 中类(class)和结构体(struct)区别
- C语言三剑客之《C专家编程》一书精华提炼