打字猴:1.70044334e+09
1700443340
1700443341 //修改计数器
1700443342
1700443343 modCount++;
1700443344
1700443345 //上次(原始)定义的数组长度
1700443346
1700443347 int oldCapacity=elementData.length;
1700443348
1700443349 //当前需要的长度超过了数组长度
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){
[ 上一页 ]  [ :1.70044334e+09 ]  [ 下一页 ]