/**
* 初始化容量
* The default initial capacity - MUST be a power of two.
*/
static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; // aka 16
/**
* 负载因子/阈值
* The load factor used when none specified in constructor
*/
static final float DEFAULT_LOAD_FACTOR = 0.75f;
背景:
HashMap存储会存在hash冲突(碰撞的状况),经过查看源码能够发现,当一个HashMap被建立时,他的初始化容量大小为16,咱们这里称做
hash桶,默认有16个桶,默认负载因子/阈值为0.75,当往map里put数据时会针对key值key.hashCode()的hashcode值进行hash(Object
key) 运算,经过index = hash & (tab.length – 1)方法计算得出数据将要存放目标桶,当存在不一样的key值通过hash计算以后获得了同
一个目标桶,则这个桶里将要存储两份数据,在存储上,这个桶里这两份数据会以链表的形式存储,当数据存储过多时,碰撞的概率会增长,单个hash
桶中的链表会变长,当下次经过get方法查询数据时,一样会通过hash获得数据存储的目标桶可是这时这个桶里存放了多条数据以链表的形式存储,
这时候须要从链表里找出我须要的数据则须要遍历链表,链表过长时,查询速度较慢,为了下降hash冲突的出现几率,保证查询的效率,扩容的概念
更值得关注。
HashMap扩容的条件:
一、HashMap中的数据达到阈值。
二、出现hash碰撞的状况。
扩容机制:
由初始化hash桶数量16和阈值0.75为例,当map中的数据达到16*0.75=12时,此时map中的数据已经达到了hashmap扩容机制的阈值,当再
次插入第13个数据时hashmp将自动扩容(前面十二个数据中有出现hash冲突的前提下),扩容的hash桶大小以2的n次方增长,16扩容以后为32。
扩容的缺点:
在开发过程当中,若是hashmap自动扩容后,而咱们又不会再往hashmap中put数据,这时扩容的意义可能就没那么大,甚至是无效扩容,因此在开
发时能够本身预估hashmap所须要的容量,经过指定hashmap的初始化容量和阈值来避免无效扩容。
总结:
HashMap的扩容、人为的设置HashMap容量和阈值限制自动扩容都是在进行时间和空间上的权衡,即内存和效率上的选择,若是但愿查询快点,
则下降负载因子,增长HashMap初始容量,下降key值hash碰撞的概率。
复制代码