ArrayList继承了Abstract类实现了List、RandomAccess、Cloneable和Serializable接口。
1、ArrayList有三个构造方法:如下
public ArrayList(int initialCapacity) {
super();//调用父类protected Abstractlist(){}
if(initialCapacity <0) {
throw new IllegalArgumentException("Illegal Capacity:" + initialCapacity);
}
this.elementData = new Object[initialCapacity];
}
public ArrayList() {
this(10);//直接调用上一个public ArrayList(int initialCapacity){}初始化
}
public ArrayList(Collection<? extends E> c) {
elementData = c.toArray();
size = elementData.length;
if(elementData.getClass() != Object[].class) {
elementData = Arrays.copyOf(elementData,size,Object[].class);
}
}
第一个是带参的构造方法,直接调用父类AbstractList的构造方法,并且如果初始长度小于零则直接抛出异常,将一开始定义的Object[]数组进行一个长度初始化;第二个是无参的构造方法直接调用第一个的构造方法然后将elementData数组初始化长度为10的数组;第三个构造方法带有一个集合类型的参数,首先将集合类型数据通过toArray()方法转换成数组,然后将其赋给elementData。
2、add(E e)
public boolean add(E e) {
ensureCapacity(size +1);
elementData[size++] = e;
return true;
}
方法中首先是调用了ensureCapacity(size+1),然后是在elementData最后位置添加了element e 并且返回true。那么ensureCapacity是怎样的一个方法呢?
3、ensureCapacity(int minCapacity)方法
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;
}
elementData = Arrays.copyOf(elementData,newCapacity);
}
}
从上面我们可以看到,在方法二中的调用了ensureCapacity(size+1)也就是此时的minCapacity就是size+1。首先对modCount计数,然后将当前的elementData数组的长度赋值给oldCapacity。此时我们就要比较minCapacity和oldCapacity哪个大,如果oldCapacity的长度(也就是当前elementData的长度)小于minCapacity(也就是size+1),那么此时我们就要对数组elementData进行一个扩容为原来长度的1.5倍长度+1。
4、add(int index,E e)返回类型为void类型
public void add(int index,E element) {
if((index > size)||(index <0)){
throw new IndexOutOfBoundsException("Index:"+index +"size"+size);
}
ensureCapacity(size+1);
System.arraycopy(elementData, index,elementData, index+1,size-index);
elementData[index] = element;
size++;
}
首先我们需要判断索引是否超出了当前的size或者index是否<0,如果是则马上抛出异常.因为此时要将内容插入,所以当前的长度要进行扩容,ensureCapacity(size+1)。扩容之后采用System.arraycopy(Object src,int srcPos,Object dest,int destPos,int length)方法将数组进行复制。从System.arraycopy方法中我们可以看到数组srcPos从src开始的元素复制到dest
import java.util.Collection;
import java.util.*;
public class ArrayList<E> extends AbstractList<E> implements List<E> ,RandomAccess,Cloneable,java.io.Serializable{
private transient Object[] elementData;
private int size;
//构造方法
public ArrayList(int initialCapacity) {
super();//调用父类protected Abstractlist(){}
if(initialCapacity <0) {
throw new IllegalArgumentException("Illegal Capacity:" + initialCapacity);
}
this.elementData = new Object[initialCapacity];
}
public ArrayList() {
this(10);//直接调用上一个public ArrayList(int initialCapacity){}初始化
}
public ArrayList(Collection<? extends E> c) {
elementData = c.toArray();
size = elementData.length;
if(elementData.getClass() != Object[].class) {
elementData = Arrays.copyOf(elementData,size,Object[].class);
}
}
public boolean addAll(Collection<? extends E> c) {
Object[] a = c.toArray();
int numNew = a.length;
ensureCapacity(size + numNew);
System.arraycopy(a, 0, elementData, size, numNew);
size += numNew;
return numNew != 0;
}
public boolean add(E e) {
ensureCapacity(size +1);
elementData[size++] = e;
return true;
}
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;
}
elementData = Arrays.copyOf(elementData,newCapacity);
}
}
public int size() {
return size;
}
public Object[] toArray() {
return Arrays.copyOf(elementData,size);
}
public <T> T[] toArray(T[] a) {
if(a.length<size)
return (T[]) Arrays.copyOf(elementData,size,a.getCalss());
System.arraycopy(elementData, 0, a, 0, size);
if(a.length>size)
a[size] = null;
return a;
}
public void add(int index,E element) {
if((index > size)||(index <0)){
throw new IndexOutOfBoundsException("Index:"+index +"size"+size);
}
elementData[index] = element;
size++;
}
public E set(int index,E element) {
RangeCheck(index);
E oldValue = (E) elementData[index];
elementData[index] = element;
return oldValue;
}
public E get(int index) {
RangeCheck(index);
return (E) elementData[index];
}
public boolean remove(Object o) {
if(o == null) {
for(int index =0;index <size;index++) {
if(elementData[index]==null) {
fastRemove(index);
return true;
}
}
}else {
for(int index = 0;index<size;index++) {
if(o.equals(elementData[index])) {
fastRemove(index);
return true;
}
}
}
return false;
}
private void fastRemove(int index) {
modCount++;
int numMoved = size -index -1;
if(numMoved >0) {
System.arraycopy(elementData,index + 1,elementData,index,numMoved);
}
elementData[--size] = null;
}
private void RangeCheck(int index) {
if(index >= size)
throw new IndexOutOfBoundsException("index:"+index+",Size:"+size);
}
}