本文主要通过HashMap构造函数讲解initialCapacity、threshold和loadFactor三个参数的前生今世。
看源码:
1 public HashMap(int initialCapacity, float loadFactor) { 2 if (initialCapacity < 0) 3 throw new IllegalArgumentException("Illegal initial capacity: " + 4 initialCapacity); 5 if (initialCapacity > MAXIMUM_CAPACITY) 6 initialCapacity = MAXIMUM_CAPACITY; 7 if (loadFactor <= 0 || Float.isNaN(loadFactor)) 8 throw new IllegalArgumentException("Illegal load factor: " + 9 loadFactor); 10 this.loadFactor = loadFactor; 11 this.threshold = tableSizeFor(initialCapacity); 12 } 13 14 15 public HashMap(int initialCapacity) { 16 this(initialCapacity, DEFAULT_LOAD_FACTOR); 17 } 18 19 20 public HashMap() { 21 this.loadFactor = DEFAULT_LOAD_FACTOR; // all other fields defaulted 22 } 23 24 25 public HashMap(Map<? extends K, ? extends V> m) { 26 this.loadFactor = DEFAULT_LOAD_FACTOR; 27 putMapEntries(m, false); 28 }
构造器源码十分简单,就是初始化几个参数,这里不做过多讲解,下面着重讲initialCapacity、threshold和loadFactor这三个参数:
size:size为HashMap中键值对总数。
initialCapacity:初始容量,从上面第11行代码我们看到,初始容量数值没有存起来,而且使用它计算阀值threshold。计算方法就是返回大于initialCapacity且最接近initialCapacity的一个2的正数幂的数字作为初始阀值。
capacity:容量。capacity就是指HashMap中桶的数量。默认值为16。一般第一次扩容时会扩容到64,之后都是以2的幂数增加。
loadFactor:装载因子,用来衡量HashMap满的程度,加载因子越大,填满的元素越多,空间利用率越高。loadFactor的默认值为0.75f。计算HashMap的实时装载因子的方法为size/capacity。至于默认值为什么是0.75,可以阅读HashMap的数据结构(一)
threshold:阀值,满足公式threshold=loadFactor*capacity。当HashMap的size大于threshold时会执行扩容(resize)操作。
理解这些参数对阅读源码和HashMap使用有很重要的作用,实际使用中,如果你可以预估元素大小,指定初始容量值,就会省去扩容操作的时间,提高程序运行效率。