HashMap实现原理和源码解析(2)

/**
  * The default initial capacity - MUST be a power of two.
  * 默认初始化容量大小16,容量大小必须是2的次方
  */
 static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; // aka 16
 
 /**
  * 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.
  * 最大的容量为 2^30
  */
 static final int MAXIMUM_CAPACITY = 1 << 30;
 
 /**
  * The load factor used when none specified in constructor.
  * 负载因子,一旦超过就会进行扩容
  */
 static final float DEFAULT_LOAD_FACTOR = 0.75f;
 /**
  * The number of times this HashMap has been structurally modified
  * Structural modifications are those that change the number of mappings in
  * the HashMap or otherwise modify its internal structure (e.g.,
  * rehash).  This field is used to make iterators on Collection-views of
  * the HashMap fail-fast.  (See ConcurrentModificationException).
  * 用于快速失败,由于HashMap非线程安全,在对HashMap进行迭代时,如果期间其他线程的参与导致HashMap的结构发生变化了
  *(比如put,remov*e等操作),需要抛出异常ConcurrentModificationException
  */
 transient int modCount;
 /**
  * The next size value at which to resize (capacity * load factor).
  *
  * @serial
  *阈值,当table == {}时,该值为初始容量(初始容量默认为16);当table被填充了,也就是为table分配内存空间后,
  *threshold一般为capacity*loadFactory。HashMap在进行扩容时需要参考threshold
  */
 int 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.
  *当一个bucket是一个链表,链表个数大于等于8时,就要树状化,也就是要从链表结构变成红黑树结构
  */
 static final int TREEIFY_THRESHOLD = 8;

  HashMap构造函数:有4个构造器,其他构造器如果用户没有传入initialCapacity 和loadFactor这两个参数,会使用默认值initialCapacity默认为16,loadFactory默认为0.75

//指定初始容量,负载因子
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);
    }
//指定初始容量
public HashMap(int initialCapacity) {
        this(initialCapacity, DEFAULT_LOAD_FACTOR);
    }
//无参
public HashMap() {
        this.loadFactor = DEFAULT_LOAD_FACTOR; // all other fields defaulted
    }
//将已存在的map放进去进行初始化,若为空则抛null异常
public HashMap(Map<? extends K, ? extends V> m) {
        this.loadFactor = DEFAULT_LOAD_FACTOR;
        putMapEntries(m, false);
    }

在常规构造器HashMap()中,没有为数组table分配内存空间,而是在执行put操作的时候才真正构建table数组。以下是put方法:

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/62b1ad2201eadfb50cbce581406e525b.html