ArrayList<String> list=new ArrayList<>();
public ArrayList() {
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
初始化了elementData,就是一个object数组;
我们再执行:list.add("wod");源码如下:
public boolean add(E e) {
ensureCapacityInternal(size + 1); // Increments modCount!!
elementData[size++] = e;
return true;
}
我们的size没有初始化,那么这里就是0;即=1,我们看方法:
private void ensureCapacityInternal(int minCapacity) {
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
}
ensureExplicitCapacity(minCapacity);
}
我们刚初始化的elementData=空数组,所以满足条件,执行里面的方法:
minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
我们传进来的minCapcity=1,而
private static final int DEFAULT_CAPACITY = 10; 它们两者取比较大的数,肯定是10了,即minCapcity=10;往下走:ensureExplicitCapacity()
protected transient int modCount = 0;
private void ensureExplicitCapacity(int minCapacity) {
modCount++;
// overflow-conscious code
if (minCapacity - elementData.length > 0)
grow(minCapacity);
}
显然,我们的10-0是大于0,则执行grow()方法:
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
public static final int MAX_VALUE = 2147483647; // 0x7fffffff
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);
}
oldCapacity=0
0+0 >> 1 =0 即newCapacity=0
0-10<0,所以执行newCapacity = minCapacity=10;
所以
newCapacity-MAX_ARRAY_SIZE肯定是小于0,不执行条件内的代码:
elementData = Arrays.copyOf(elementData, newCapacity);把elementData的数据复制到elementData,并且指定elementData的大小为10;
所以第一次添加数据时,会初始化一遍数据elementData,大小为10;
然后elementData[0]=object ; size++
第二次添加数据时,看看会发生什么:
public boolean add(E e) {
ensureCapacityInternal(size + 1); // Increments modCount!!
elementData[size++] = e;
return true;
}
这时,size=1;加一就是2,执行:ensureCapacityInternal(2)
private void ensureCapacityInternal(int minCapacity) {
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
}
ensureExplicitCapacity(minCapacity);
}
elementData不是空数组了,则不走条件内的,直接走外面,ensureExplicitCapacity(2)
private void ensureExplicitCapacity(int minCapacity) {
modCount++;
// overflow-conscious code
if (minCapacity - elementData.length > 0)
grow(minCapacity);
}
这里modCount++,第二次modCount=2了;
因为我们这里minCapacity=2,elementData的长度是10,所以2-10肯定是小于零,所以不走grow(),添加元素到这里就完成了
到这,我们总结一下:
1、当我们初始化new ArrayList() 时候,ArrayList会初始化了elementData,一个object数组;
2、当我们第一次list.add()的时候,ArrayList会先将elementData处理成一个长度为10的空数组,然后再将要放的对象,存放到下标为0的地方,同时size变量++;
我们刚在方法ensureExplicitCapacity()里面,
private void ensureExplicitCapacity(int minCapacity) {
modCount++;
// overflow-conscious code
if (minCapacity - elementData.length > 0)
grow(minCapacity);
}
在什么时候,添加数据的时候,什么情况下会执行:grow(minCapacity);
肯定是满足条件(minCapacity - elementData.length > 0),什么情况下会满足呢,我们来看一看;
我们看到:minCapacity,它是表示size+1,size是表示我们添加过几条数据,就是在data数组里面,有多少条不为空,那size就是多少;当我们已经全部添加满的时候,也就是size=10了,即将要添加第11条数据的时候,则即:size+1,或者:10+1,这时我们的minCapacity=11;
那么,11-10肯定是大于0,则执行grow( 11 )方法;
我们继续看grow()方法:
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);
}
整理如下:
minCapacity=11,(是我们传过来的参数)
oldCapacity=10;
newCapacity=10 + (10 >> 1)=10+ 5;(>> 1 左移一位,相当于除以2,右移一位相当于乘以2)
=15
if(15-11<0){
4<0,肯定不成立,即不满足条件,不执行
}
if (15 - MAX_ARRAY_SIZE > 0){
MAX_ARRAY_SIZE是一个很大 的值,15减一个大数,肯定小于0,则不满足条件,不执行
}
最后执行:
elementData = Arrays.copyOf(elementData, newCapacity);
最后:elementData[size++] = e; 即先执行size++
再:elementData[11] = e
所以到这,我们的添加数组,就全部结束啦;我们再总结一下:
当我们要添加大于数组长度的数据时,ArrayList会记性扩容,扩容后的数组长度为:原数据长度+二分之一原数组长度,这么说,不简便,即:扩容后的数组长度为原来数组的1.5倍;