当前位置: 首页 > news >正文

HashMap源码分析笔记(一)

一、结构

HashMap的结构由数组和链表组成,可以说是一个链表类型的数组:

快速定位方式:key值得hash变换作为数组索引快速找到对应数组块,之后通过hash值对比从链表中查找到匹配项。

hash函数:

hash()

key的hash值是实际是key的hashCode值的低16位与高16位异或结果。之所以这样是为了减少数组定位时发生哈希碰撞。

数组下标是这样确定的:

i =(n-1)& hash //n=tab.length(),hash = hash(key)

从数组下标确定算法可以看出,实际参与运算的基本都是hash的低位,这样发生哈希冲突的可能性就比较高,所以hash函数中才会用hashcode值高低位取异或;

 

 

二、默认参数

 1 /**
 2  * The default initial capacity - MUST be a power of two.
 3  */
 4 static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; // aka 16
 5 
 6 /**
 7  * The maximum capacity, used if a higher value is implicitly specified
 8  * by either of the constructors with arguments.
 9  * MUST be a power of two <= 1<<30.
10  */
11 static final int MAXIMUM_CAPACITY = 1 << 30;
12 
13 /**
14  * The load factor used when none specified in constructor.
15  */
16 static final float DEFAULT_LOAD_FACTOR = 0.75f;

 

规定HashMap容量总为2的幂次方,最小16,最大2的30次方;

DEFAULT_LOAD_FACTOR 默认的负载因子,参与通过无参构造的HashMap初始容量计算。

三、属性

1 transient Node<K,V>[] table;
2 transient Set<Map.Entry<K,V>> entrySet;
3 transient int size;
4 //容量阈值
5 int threshold;
6 //负载因子
7 final float loadFactor;

当通过无参构造函数初始化时,loadFactor = DEFAULT_LOAD_FACTOR。实际上通过无参构造HashMap时,初始容量为 = DEFAULT_INITIAL_CAPACITY * loadFactor(见方法rsize())。

四、构造函数

hashMap有4个构造函数;

一个无参构造,初始容量和负载因子都取默认值;

一个通过已有Map构造;

两个自定义容量构造;

jdk1.8的构造函数并没有初始化table,table初始化放在了第一次put中。

 

 1 public HashMap(int initialCapacity, float loadFactor) {
 2     if (initialCapacity < 0)
 3         throw new IllegalArgumentException("Illegal initial capacity: " +
 4                                            initialCapacity);
 5     if (initialCapacity > MAXIMUM_CAPACITY)
 6         initialCapacity = MAXIMUM_CAPACITY;
 7     if (loadFactor <= 0 || Float.isNaN(loadFactor))
 8         throw new IllegalArgumentException("Illegal load factor: " +
 9                                            loadFactor);
10     this.loadFactor = loadFactor;
11     this.threshold = tableSizeFor(initialCapacity);
12 }

 

除了无参构造,都应用到一个方法tableSizeFor();

tableSizeFor

此算法计算出大于等于入参的最小2的幂次方,由于规定map容量必须为2的幂次方,所以经由此方法得出自定义的最佳容量。

 

转载于:https://www.cnblogs.com/caster-xzn/p/10309314.html

相关文章:

  • redis 学习笔记-cluster集群搭建
  • Java定义三个点Object...
  • Python学习链接
  • js给图层添加动态样式
  • LaTeX :font size 修改字体大小的几种方式
  • 4.1链表
  • 信号(SIGNAL)与槽(SLOT)
  • 类的约束 和 异常处理
  • jzoj3208. 【JSOI2013】编程作业(kmp)
  • JS中arguments对象
  • (七)Knockout 创建自定义绑定
  • 【特征提取】MultiBlock-LBP特征
  • STM32L431驱动带UC1698芯片调试记录
  • 函数模板
  • Java发布webservice应用并发送SOAP请求调用
  • [case10]使用RSQL实现端到端的动态查询
  • [原]深入对比数据科学工具箱:Python和R 非结构化数据的结构化
  • CSS相对定位
  • es6(二):字符串的扩展
  • Java程序员幽默爆笑锦集
  • Nacos系列:Nacos的Java SDK使用
  • SegmentFault 2015 Top Rank
  • Storybook 5.0正式发布:有史以来变化最大的版本\n
  • 成为一名优秀的Developer的书单
  • 创建一种深思熟虑的文化
  • 从零搭建Koa2 Server
  • 计算机常识 - 收藏集 - 掘金
  • 前端 CSS : 5# 纯 CSS 实现24小时超市
  • 网络应用优化——时延与带宽
  • 微信支付JSAPI,实测!终极方案
  • 为视图添加丝滑的水波纹
  • 译自由幺半群
  • ​软考-高级-系统架构设计师教程(清华第2版)【第20章 系统架构设计师论文写作要点(P717~728)-思维导图】​
  • # 日期待t_最值得等的SUV奥迪Q9:空间比MPV还大,或搭4.0T,香
  • ###STL(标准模板库)
  • #define与typedef区别
  • %@ page import=%的用法
  • (BFS)hdoj2377-Bus Pass
  • (day 12)JavaScript学习笔记(数组3)
  • (二)pulsar安装在独立的docker中,python测试
  • (翻译)Quartz官方教程——第一课:Quartz入门
  • (附源码)springboot猪场管理系统 毕业设计 160901
  • (篇九)MySQL常用内置函数
  • (四)库存超卖案例实战——优化redis分布式锁
  • (五)大数据实战——使用模板虚拟机实现hadoop集群虚拟机克隆及网络相关配置
  • (学习日记)2024.02.29:UCOSIII第二节
  • (学习日记)2024.03.25:UCOSIII第二十二节:系统启动流程详解
  • (一)VirtualBox安装增强功能
  • (已更新)关于Visual Studio 2019安装时VS installer无法下载文件,进度条为0,显示网络有问题的解决办法
  • (转)Sublime Text3配置Lua运行环境
  • (转)Windows2003安全设置/维护
  • .java 指数平滑_转载:二次指数平滑法求预测值的Java代码
  • .net Application的目录
  • .NET Micro Framework 4.2 beta 源码探析
  • .net 程序 换成 java,NET程序员如何转行为J2EE之java基础上(9)