我们由上面test2()方法可知,一个List,调用list.toArray()返回的Object数组的真实类型不一定是Object数组([Ljava.lang.Object;),当我们调用 Object[] objArray = collection.toArray(), objArray并不一定能够存放Object对象,所以上面的源码中对这种情况进行了判断。
我们接着看ArrayList中的方法:
add(E),当我们添加数据的时候,会遇到的一个问题就是:当里面的数组满了,没有可用的容量的怎么办?
/**
*插入对象,首先将size+1,产生一个minCapacity的变量,调用ensureCapacity(minCapacity)方法保证数组在插入一个元素时有可用的��量,然后将元素e放到数组elementData的size位置,最后将size+1
*/
public boolean add(E e) {
ensureCapacity(size + 1); // Increments modCount!!
elementData[size++] = e;
return true;
}
/**
*必要时数组的扩容 (如果想调整ArrayList的容量增长策略,可以继承ArrayList,override ensureCapacity()方法即可),
首先将modCount+1,modeCount表示修改数组结构的次数(维护在父类AbstractList中),如果入参minCapacity大于目前数组elementData的容量,则将容量扩展到 (oldCapacity * 3)/2 + 1,
若此时容量仍然小于 minCapacity,则直接将minCapacity设置为最新的容量,
最后使用Arrays.copyof()方法将原来elementData中元素copy到新的数组中,并将新数组赋值给elementData.
*/
public void ensureCapacity(int minCapacity) {
modCount++;
int oldCapacity = elementData.length;
if (minCapacity > oldCapacity) {
Object oldData[] = elementData;
int newCapacity = (oldCapacity * 3)/2 + 1;
if (newCapacity < minCapacity)
newCapacity = minCapacity;
// minCapacity is usually close to size, so this is a win:
elementData = Arrays.copyOf(elementData, newCapacity);
}
}
/**
*在指定下标Index处插入元素element,首先判断下标index的参数是否有效(不能小于0,不能大于size),否则抛出IndexOutOfBoundsException异常,然后调用ensureCapacity(size+1)要确保数组中有足够的容量来插入数据,
*然后调用System.arraycopy()方法, 从index下标开始,将elementData数组元素copy到 从index+1开始的地方,copy的长度为size-index,这样index下标处的位置就空了出来,然后将元素element放到下标为index处的位置,最后将size++.
*我们看到使用这个方法相比add(E),多了一步数组元素的复制的代价。
*/
public void add(int index, E element) {
if (index > size || index < 0)
throw new IndexOutOfBoundsException(
"Index: "+index+", Size: "+size);
ensureCapacity(size+1); // Increments modCount!!
System.arraycopy(elementData, index, elementData, index + 1,
size - index);
elementData[index] = element;
size++;
}
/**
*将元素element设值到下标为index处,返回原来index处的旧值。
*/
public E set(int index, E element) {
RangeCheck(index);
//获取index下标的旧值
E oldValue = (E) elementData[index];
//设值新的元素element到index处
elementData[index] = element;
return oldValue;
}
//边界检查,index越界的话,抛出异常IndexOutOfBoundsException
private void RangeCheck(int index) {
if (index >= size)
throw new IndexOutOfBoundsException(
"Index: "+index+", Size: "+size);
}
/**
*将指定集合c中的元素按照其迭代器返回的顺序追加到本集合中,只要将任何一个元素插入到集合中都会返回true
*/
public boolean addAll(Collection<? extends E> c) {
Object[] a = c.toArray();
int numNew = a.length;
//确保(size+a.length)有足够的容量去插入新元素
ensureCapacity(size + numNew); // Increments modCount
//将数组a的内容追加到elementData数组的最后
System.arraycopy(a, 0, elementData, size, numNew);
size += numNew;
//只要插入的元素个数>0就返回true
return numNew != 0;
}
我们再看删除的方法