集合是JAVA编程中使用非常广泛的,它就像万能容器,盛装万物,而且这个万能容器还可以无限变大(如果条件允许)。当这容器的量变得非常大的时候,它的初始容量就会显得很重要,因为扩容是需要消耗大量的资源的。而且在性能方便也是影响甚大。
一 、List测试代码
@Test
public void Test() {
long begin1 = System.currentTimeMillis();
List<Integer> list1 = new ArrayList<>();
for(int i = 0 ; i < 1000000; i++){
list1.add(i);
}
long end1 = System.currentTimeMillis();
System.out.println("list1 time:" + (end1 - begin1));
long begin2 = System.currentTimeMillis();
List<Integer> list2 = new ArrayList<>(1000000);
for(int i = 0 ; i < 1000000; i++){
list2.add(i);
}
long end2 = System.currentTimeMillis();
System.out.println("list2 time:" + (end2 - begin2));
}
上面代码两个list都是插入1000000条数据,只不过list1没有没有申请初始化容量,而list2初始化容量1000000。那运行结果如下:
list1 time:81
list2 time:18
从运行结果可以看出list2的速度是list1的2倍到6倍。这是因为ArrayList的扩容机制是比较消耗资源的。来看看ArrayList的add方法:
/**
* Appends the specified element to the end of this list.
*
* @param e element to be appended to this list
* @return <tt>true</tt> (as specified by {@link Collection#add})
*/
public boolean add(E e) {
ensureCapacityInternal(size + 1); // Increments modCount!!
elementData[size++] = e;
return true;
}
private void ensureCapacityInternal(int minCapacity) {
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
}
ensureExplicitCapacity(minCapacity);
}
private void ensureExplicitCapacity(int minCapacity) {
modCount++;
// overflow-conscious code
if (minCapacity - elementData.length > 0)
grow(minCapacity);
}
/**
* Increases the capacity to ensure that it can hold at least the
* number of elements specified by the minimum capacity argument.
*
* @param minCapacity the desired minimum capacity
*/
private void grow(int minCapacity) {
// overflow-conscious code
int oldCapacity = elementData.length;
int newCapacity = oldCapacity + (oldCapacity >> 1);
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity);
// minCapacity is usually close to size, so this is a win:
elementData = Arrays.copyOf(elementData, newCapacity);
}
ArrayList每次新增一个元素,就会检测ArrayList的当前容量是否已经到达临界点,如果到达临界点则会扩容1.5倍。然而ArrayList的扩容以及数组的拷贝生成新的数组是相当耗资源的。所以若事先已知集合的使用场景,知道集合的大概范围,我们最好是指定初始化容量,这样对资源的利用会更加好,尤其大数据量的前提下,效率的提升和资源的利用会显得更加具有优势。
二 Map 测试代码