首先,这三个概念说下。初始大小,就是创建时可容纳的默认元素个数;加载因子,表示某个阀值,用0~1之间的小数来表示,当已有元素占比达到这个阀值后,底层将进行扩容操作;扩容方式,即指定每次扩容后的大小的规则,比如翻倍等。
Class | 初始大小 | 加载因子 | 扩容倍数 | 底层实现 | Code | 是否线程安全 | 同步方式 |
ArrayList | 10 | 1 | 1.5倍 | Object数组 | int newCapacity = oldCapacity + (oldCapacity >> 1); ">>"右移符号,所以是除以2,所以新的容量是就的1.5倍 Arrays.copyOf 调用 System.arraycopy 扩充数组 | 线程不安全 | - |
Vector | 10 | 1 | 2倍 | Object数组 | int newCapacity = oldCapacity + ((capacityIncrement > 0) ? capacityIncrement : oldCapacity); capacityIncrement默认为0,所以是加上本身,也就是2*oldCapacity,2倍大小 Arrays.copyOf 调用 System.arraycopy 扩充数组 | 线程安全 | synchronized |
HashSet | 16 | 0.75f | 2倍 | HashMap<E,Object> | add方法实际调用HashMap的方法put | 线程不安全 | - |
HashMap | 16 | 0.75f | 2倍 | Map.Entry | void addEntry(int hash, K key, V value, int bucketIndex) { if ((size >= threshold) && (null != table[bucketIndex])) { resize(2 * table.length); hash = (null != key) ? hash(key) : 0; bucketIndex = indexFor(hash, table.length); } createEntry(hash, key, value, bucketIndex); } | 线程不安全 | - |
Hashtable | 11 | 0.75f | 2倍+1 | Hashtable.Entry数组 | int newCapacity = (oldCapacity << 1) + 1; if (newCapacity - MAX_ARRAY_SIZE > 0) { if (oldCapacity == MAX_ARRAY_SIZE) return; newCapacity = MAX_ARRAY_SIZE; } | 线程安全 | synchronized |
最后补充,计算每次的扩容边界值的方式是:threshold = (int) Math.min(initialCapacity * loadFactor, MAXIMUM_CAPACITY + 1);