集合是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 测试代码