通过阅读源码,java中ArrayList其本质上是由object数组封装而成,其默认长度为10.
下面是自定义模仿的ArrayList,主要是重写了其add方法:
public class ArrayList implements Collection {
Object[] objects=new Object[10];
int index=0;
public void add(Object o){
if(index == objects.length){
Object[] newObjects=new Object[objects.length*2];
System.arraycopy(objects, 0, newObjects, 0, objects.length);
objects=newObjects;
}
objects[index]=o;
index++;
}
public int size(){
return index;
}
@Override
public Iterator iterator() {
return new ArrayListIterator();
}
private class ArrayListIterator implements Iterator{
private int currentIndex=0;
@Override
public Object next() {
Object o=objects[currentIndex];
currentIndex++;
return o;
}
@Override
public boolean hasNext() {
if(currentIndex >= index)return false;
else return true;
}
}
}
这里我们主要解释下ArrayList的扩容机制,ArrayList是新建一个object对象数组,初始索引为0,当其里面的对象数量达到10之后,会新建一个object数组,长度为原来的2倍,将原数组的中的对象copy到新数组中,最后将新数组赋值给原数组即可。
下面我们结合源码看看,
可以看到,其初始化时,默认创建一个长度为10的object数组,再看添加元素的代码
添加元素将size+1,,即当前ArrayList中元素的个数传到ensureCapacity中判断,当其长度大于10时,会将原有长度扩大1.5倍,我的jdk是1.6,在1.7中是这样的 :
int newCapacity = oldCapacity + (oldCapacity >> 1);
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity);
采用的是向右移一位即除以2,由于计算机底层运算是二进制,所以做加减乘除运算时移位比运算符计算性能会更好。长度变为原来的1.5倍,并且增加了object最大长度的判断,即int的最大值。