前沿拓展:java整形多少位
你看一下 美链网 上面的介绍,烟针马吸度引们药逐来量还是多比较再选择比较好希望能给您提供帮助,可以给个大大的赞不。前言
阅读前请先看看如下几个问题,如果有不清楚的地方看完本文会有收获

在JDK的HashMap中存在无参构造函数和有参构造函数,有参构造函数中又存在带有指定容量和加载因子的构造方法和只带有指定容量的构造方法,分析下 HashMap(int initialCapacity) 构造方法
public HashMap(int initialCapacity) { this(initialCapacity, DEFAULT_LOAD_FACTOR); } 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); }该方法逻辑比较简单首先校验下容量有没有超多大值,没有的话设置下加载
算法分析生成扩容阈值的算法如下,该算法的巧妙的用位运算生成大于等于指定容量的小的2的幂次值例如如果给定一个数为14那么算出大于14的2的小指数幂等于16
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的整数次幂对应的二进制数有效位为1且有效位后所有位为0,如下图所示

假设cap=14,cap-1 =13 其二进制位1101经过下图的变化后发现在第一次位运算后所有有效位都为1111,因此在剩下的四次位运算后终结果就是1111,后将1111+1=10000得到十进制数位16。

构造方法虽然设置了hashmap的threshold但是并没有真正设置hashmap的容量大小,真正容量大小是在向hashmap中插入第一个元素时进行设置
HashMap 内存分配时机经过构造函数new的Hashmap对象并未真正分配内存空间,这其实是一种优化因为在构造方法就分配内存空间后很久才进行插入操作那么这部分内存其实是浪费的。因此在put操作时会进行判断如果第一次插入则通过resize方法进行进行分配空间。第一次插入时分配的空间大小即为tablesizefor方法返回大小
这种分配方式满足程序局部性原理,在写代码时可以借鉴


本文只截取部分resize方法分析,剩余扩容逻辑会在新文章中进行讲解。
首先判断table 是否为空,因为初始化阶段table=null所以oldCap=0由于在hashmap中带参数的构造方法通过tableSizeFor方法设置了threshold因此table数据的容量为oldThr如果使用无参数构造方法newCap&newThr均使用默认值后创建数据并指向table
HashMap使用巧妙且的算法获取了大于等于给定容量的小2的整数幂,所以在根据hashcode计算元素所属hash表的位置时通过hashcode与(hash表长度-1)进行取模快速定位。在插入进行内存分配机制极大的避免了内存浪费而且满足了局部性原理同样值得学习
拓展知识:java整形多少位
还有其他疑惑?想了解更多?可以点击 【在线咨询】