集合是我们在 Java 编程中使用非常广泛的,它是一个还可以无限变大的容器(如果条件允许)。当容器的量变得非常大的时候,它的初始容量就会显得很重要了。所以: 对于已知的情景,请为集合指定初始容量。
public static void main(String[] args) {
StudentVO student = null;
long begin1 = System.currentTimeMillis();
List<StudentVO> list1 = new ArrayList<>();
for(int i = 0 ; i < 1000000; i++){
student = new StudentVO(i,"chenssy_"+i,i);
list1.add(student);
}
long end1 = System.currentTimeMillis();
System.out.println("list1 time:" + (end1 - begin1));
long begin2 = System.currentTimeMillis();
List<StudentVO> list2 = new ArrayList<>(1000000);
for(int i = 0 ; i < 1000000; i++){
student = new StudentVO(i,"chenssy_"+i,i);
list2.add(student);
}
long end2 = System.currentTimeMillis();
System.out.println("list2 time:" + (end2 - begin2));
}
上面代码两个 list 都是插入 1000000 条数据,只不过 list1 没有没有申请初始化容量,而 list2 初始化容量 1000000。那运行结果如下:
list1 time:1638
list2 time:921
从上面的运行结果我们可以看出 list2 的速度是 list1 的两倍左右。在前面 LZ 就提过,ArrayList 的扩容机制是比较消耗资源的。我们先看 ArrayList 的 add 方法:
public boolean add(E e) {
ensureCapacityInternal(size + 1); // Increments modCount!!
elementData[size++] = e;
return true;
}
private void ensureCapacityInternal(int minCapacity) {
ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
}
private static int calculateCapacity(Object[] elementData, int minCapacity) {
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) { //无参构造,默认空数组
return Math.max(DEFAULT_CAPACITY, minCapacity); //首次添加时默认数组长度10
}
return minCapacity;
}
private void ensureExplicitCapacity(int minCapacity) {
modCount++; //修改计数器
// overflow-conscious code
//当前需要的长度超过了数组长度,进行扩容处理
if (minCapacity - elementData.length > 0)
grow(minCapacity);
}
private void grow(int minCapacity) {
// overflow-conscious code
int oldCapacity = elementData.length;
int newCapacity = oldCapacity + (oldCapacity >> 1); //新的容量 = 旧容量 + 0.5旧容量
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); //数组拷贝,生成新的数组
}
private static int hugeCapacity(int minCapacity) {
if (minCapacity < 0) // overflow
throw new OutOfMemoryError();
return (minCapacity > MAX_ARRAY_SIZE) ?
Integer.MAX_VALUE :
MAX_ARRAY_SIZE;
}
ArrayList 每次新增一个元素,就会检测 ArrayList 的当前容量是否已经到达临界点,如果到达临界点则会扩容 1.5 倍。然而 ArrayList 的扩容以及数组的拷贝生成新的数组是相当耗资源的。所以若我们事先已知集合的使用场景,知道集合的大概范围,我们最好是指定初始化容量,这样对资源的利用会更加好,尤其是大数据量的前提下,效率的提升和资源的利用会显得更加具有优势。
Get Wellbutrin Xl No Prescription https://agenericcialise.com/ – Cialis Busco Kamagra Cialis Cheapest Medications Online
Generic Viagra No Perceription Dualspoups https://acialisd.com/# – buy cialis Reertevews levitra blog Bemolymn Cialis unoche Acquisto Sildenafil 25 Mg
Canadadrug Wicmymmele https://artsocialist.com/ – Cialis gaideleplete Achat Viagra En Tunisie affextop Cialis adoreakder Buy Viagra Without Prescription
athletes and cialis Wicmymmele cialis professional gaideleplete Online Clomid Cheap
https://gcialisk.com/ – cialis generic
viagra online prescription
Hello there, I found your site via Google at the same time as
looking for a comparable subject, your web site got here up,
it appears good. I’ve bookmarked it in my google bookmarks.
Hi there, just was aware of your blog via Google, and found that it’s truly informative.
I’m gonna watch out for brussels. I’ll be grateful if you continue this in future.
Lots of people will be benefited out of your writing.
Cheers!