注:笔者所使用的jdk为1.8,因本人水平有限,难免会有错误,请批评指正,弥补不足,多谢,另转载请注明出处。
public class HashMap extends AbstractMap
implements Map, Cloneable, Serializable
可以看到,HashMap类继承了AbstractMap类,实现了Map
我们一个一个来看下HashMap中定义的属性、静态内部类和方法
1.默认初始容量(1<<4 的值为16)
/**
* The default initial capacity - MUST be a power of two.
*/
static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; // aka 16
HashMap是使用哈希表的数据结构存储数据的,这个初始化数量就是初始化哈希表中筒的数量,也就是下图哈希表中左边16个存储空间。如果我们在创建HashMap没有指定桶的数量的话,那么默认就是16个,初始值必须是2的倍数
(图片来自百度)
2.最大容量(1<<30 这是一个很大的数,2的30次方,为1073741824)
/**
* The maximum capacity, used if a higher value is implicitly specified
* by either of the constructors with arguments.
* MUST be a power of two <= 1<<30.
*/
static final int MAXIMUM_CAPACITY = 1 << 30;
这个表示哈希表的桶的数量最大为2的30次方个,这个我们很少涉及,一般会不临时存储到这个数量级的数据,最大容量值同样也必须是2的倍数
3.默认加载因子
/**
* The load factor used when none specified in constructor.
*/
static final float DEFAULT_LOAD_FACTOR = 0.75f;
这个加载因子的作用就是,比如我们创建一个HashMap但是没有指定初始容量,那么创建的哈希表有16个桶,但是这16个桶很有可能不够用啊,那么就需要扩展桶的数量,那么问题来了,什么时候应该扩展桶的数量那?答案就在这个加载因子上了。答案是当桶的数量达到 当前桶数量*加载因子时,就将桶的数量扩充为当前桶数量的2倍。比如目前16个桶,那么当16*0.75=12,当12个桶存储数据后,哈希表的桶会扩充为32个,用来准备存储更多的数据。
4.TREEIFY_THRESHOLD
/**
* The bin count threshold for using a tree rather than list for a
* bin. Bins are converted to trees when adding an element to a
* bin with at least this many nodes. The value must be greater
* than 2 and should be at least 8 to mesh with assumptions in
* tree removal about conversion back to plain bins upon
* shrinkage.
*/
static final int TREEIFY_THRESHOLD = 8;
这个我们来看官方jdk的注释,注释是“使用树而不使用链表的阈值,当桶中元素超过这个阈值时,使用树容器替换链表”。顾名思义,在哈希表中,每个桶中的数据是以链表的形式存储的,但是当元素数量达到8时,使用树的结构存储桶中的数据。
5.UNTREEIFY_THRESHOLD
/**
* The bin count threshold for untreeifying a (split) bin during a
* resize operation. Should be less than TREEIFY_THRESHOLD, and at
* most 6 to mesh with shrinkage detection under removal.
*/
static final int UNTREEIFY_THRESHOLD = 6;
这个我们看官方的jdk注释,注释是“执行调整大小操作,如果桶中的元素小于这个阈值,则使用链表替换树”
6.MIN_TREEIFY_CAPACITY
/**
* The smallest table capacity for which bins may be treeified.
* (Otherwise the table is resized if too many nodes in a bin.)
* Should be at least 4 * TREEIFY_THRESHOLD to avoid conflicts
* between resizing and treeification thresholds.
*/
static final int MIN_TREEIFY_CAPACITY = 64;
注释的意思是“可被树化的最小表容量”。我们从上面可以知道,哈希表中的桶中的元素可以用链表或者树来存储,那么什么时候用树存储那?答案是需要满足哈希桶的数量要达到64这个条件,并且需要是TREEIFY_THRESHOLD数量的4倍以上。