打字猴:1.70044335e+09
1700443350
1700443351 if(minCapacity>oldCapacity){
1700443352
1700443353 Object oldData[]=elementData;
1700443354
1700443355 //计算新数组长度
1700443356
1700443357 int newCapacity=(oldCapacity*3)/2+1;
1700443358
1700443359 if(newCapacity<minCapacity)
1700443360
1700443361 newCapacity=minCapacity;
1700443362
1700443363 //数组拷贝,生成新数组
1700443364
1700443365 elementData=Arrays.copyOf(elementData, newCapacity);
1700443366
1700443367 }
1700443368
1700443369 }
1700443370
1700443371 注意看新数组的长度计算方法,并不是增加一个元素,elementData的长度就加1,而是在达到elementData长度的临界点时,才将elementData扩容1.5倍,这样实现有什么好处呢?好处是避免了多次调用copyOf方法的性能开销,否则每加一个元素都要扩容一次,那性能岂不是非常糟糕?!
1700443372
1700443373 可能有读者要问了,这里为什么是1.5倍,而不是2.5倍、3.5倍?这是一个好问题,原因是一次扩容太大(比如扩容2.5倍),占用的内存也就越大,浪费的内存也就越多(1.5倍扩容,最多浪费33%的数组空间,而2.5倍则最多可能浪费60%的内存);而一次扩容太小(比如每次扩容1.1倍),则需要多次对数组重新分配内存,性能消耗严重。经过测试验证,扩容1.5倍即满足了性能要求,也减少了内存消耗。
1700443374
1700443375 现在我们知道了ArrayList的扩容原则,那还有一个问题:elementData的默认长度是多少呢?答案是10,如果我们使用默认方式声明ArrayList,如new ArrayList(),则elementData的初始长度就是10。我们来看ArrayList的无参构造:
1700443376
1700443377 //无参构造,我们通常用得最多的就是这个
1700443378
1700443379 public ArrayList(){
1700443380
1700443381 //默认是长度为10的数组
1700443382
1700443383 this(10);
1700443384
1700443385 }
1700443386
1700443387 //指定数组长度的有参构造
1700443388
1700443389 public ArrayList(int initialCapacity){
1700443390
1700443391 super();
1700443392
1700443393 if(initialCapacity<0)
1700443394
1700443395 throw new IllegalArgumentException(“Illegal Capacity:”+initialCapacity);
1700443396
1700443397 //声明指定长度的数组,容纳element
1700443398
1700443399 this.elementData=new Object[initialCapacity];
[ 上一页 ]  [ :1.70044335e+09 ]  [ 下一页 ]