从源码分析HashMap集合之属性(一)

注:笔者所使用的jdk为1.8,因本人水平有限,难免会有错误,请批评指正,弥补不足,多谢,另转载请注明出处。

我们首先来看下一下HashMap类

public class HashMap extends AbstractMap
    implements Map, Cloneable, Serializable

可以看到,HashMap类继承了AbstractMap类,实现了Map接口,Cloneable接口,Serializable接口

从源码分析HashMap集合之属性(一)_第1张图片

我们一个一个来看下HashMap中定义的属性、静态内部类和方法

1.属性:

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的倍数

从源码分析HashMap集合之属性(一)_第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倍以上。

 

在后面的文章中继续分享HashMap中的内部静态类和方法源码

你可能感兴趣的:(java集合源码分析)