ArrayList和Vector都是集合,允许重复的key,允许null key
查看源码发现,ArrayList和Vector都继承了AbastractList抽象类,实现类List接口(List接口继承了Collection接口)、RandomAccess接口、Cloneable接口、Serializable接口
public class ArrayList<E> extends AbstractList<E>
implements List<E>, RandomAccess, Cloneable, java.io.Serializable
public class Vector<E>
extends AbstractList<E>
implements List<E>, RandomAccess, Cloneable, java.io.Serializable
然后通过一段代码执行来查看源码来分析两者之间的不同点
ArrayList<Integer> integers=new ArrayList<Integer>(10);
integers.add(2);
integers.add(1);
integers.add(null);
integers.add(null);
integers.remove(1);
System.out.println(integers.size());
首先看下ArrayList属性
/**
* Default initial capacity.
*/
private static final int DEFAULT_CAPACITY = 10;//AraryList默认容量
/**
* Shared empty array instance used for empty instances.
*/
private static final Object[] EMPTY_ELEMENTDATA = {};//空对象数组
/**
* Shared empty array instance used for default sized empty instances. We
* distinguish this from EMPTY_ELEMENTDATA to know how much to inflate when
* first element is added.
*/
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};//默认空对象数组
/**
* The array buffer into which the elements of the ArrayList are stored.
* The capacity of the ArrayList is the length of this array buffer. Any
* empty ArrayList with elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA
* will be expanded to DEFAULT_CAPACITY when the first element is added.
*/
transient Object[] elementData; // non-private to simplify nested class access 存储对象的数组
/**
* The size of the ArrayList (the number of elements it contains).
*
* @serial
*/
private int size;//ArrayList的容量
执行ArrayList integers=new ArrayList();调用无参构造方法,设置对象数组为DEFAULTCAPACITY_EMPTY_ELEMENTDATA也就是{}
public ArrayList(int initialCapacity) {
if (initialCapacity > 0) {//初始容量>0,new一个Object数组,容量为initialCapacity
this.elementData = new Object[initialCapacity];
} else if (initialCapacity == 0) {//初始容量为0,
this.elementData = EMPTY_ELEMENTDATA;
} else {//其他值,报错
throw new IllegalArgumentException("Illegal Capacity: "+
initialCapacity);
}
}
然后执行 integers.add(2);
public boolean add(E e) {
ensureCapacityInternal(size + 1); // Increments modCount!!
elementData[size++] = e;//在数组默认添加一个元素,然后size+1
return true;
}
该方法主要就是调用ensureCapacityInternal方法,进入到这个方法
private void ensureCapacityInternal(int minCapacity) {
ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
}
进入到calculateCapacity(elementData, minCapacity)方法
private static int calculateCapacity(Object[] elementData, int minCapacity) {
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {//如果elementData=DEFAULTCAPACITY_EMPTY_ELEMENTDATA也就是{}
return Math.max(DEFAULT_CAPACITY, minCapacity);//返回DEFAULT_CAPACITY和minCapacity的最大值
}
return minCapacity;
}
通过calculateCapacity就得到了要修改的容量
进入到ensureExplicitCapacity方法
private void ensureExplicitCapacity(int minCapacity) {
modCount++;//修改次数+1
// overflow-conscious code
if (minCapacity - elementData.length > 0)//判断当前要修改的容量是否大于当前数组长度
grow(minCapacity);//扩容
}
进入到grow方法
private void grow(int minCapacity) {
// overflow-conscious code
int oldCapacity = elementData.length;//当前容量
int newCapacity = oldCapacity + (oldCapacity >> 1);//新容量增加原来的0.5
if (newCapacity - minCapacity < 0)//取newCapacity 和minCapacity的大者
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);//拷扩展数组容量为newCapacity,并将赋值为当前数组elementData
}
public static <T> T[] copyOf(T[] original, int newLength) {
return (T[]) copyOf(original, newLength, original.getClass());
}
public static <T,U> T[] copyOf(U[] original, int newLength, Class<? extends T[]> newType) {
@SuppressWarnings("unchecked")
T[] copy = ((Object)newType == (Object)Object[].class)
? (T[]) new Object[newLength]
: (T[]) Array.newInstance(newType.getComponentType(), newLength);
System.arraycopy(original, 0, copy, 0,
Math.min(original.length, newLength));
return copy;
}
查看Arrays.copy方法,发现底层是用的 public static native void arraycopy(Object src, int srcPos,
Object dest, int destPos,
int length); native方法
public static native void arraycopy(Object src, int srcPos,
Object dest, int destPos,
int length);
执行integers.remove(1);
public E remove(int index) {
rangeCheck(index);//检验当前索引是否越界
modCount++;//修改次数加1
E oldValue = elementData(index);//保存旧值
int numMoved = size - index - 1;//numMoved=4-1-1=2
if (numMoved > 0)
System.arraycopy(elementData, index+1, elementData, index, numMoved);
elementData[--size] = null; // clear to let GC do its work
//将最后一个置为null方便gc
return oldValue;
}
进入 rangeCheck(index);//检验当前索引是否越界
private void rangeCheck(int index) {
if (index >= size)
throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}
然后运行Vector测试代码
Vector<Integer> integers1=new Vector<Integer>(10);
integers1.add(2);
integers1.add(1);
integers1.add(null);
integers1.add(null);
integers1.remove(1);
System.out.println(integers1.size());
查看Vector的参数
/**
* The array buffer into which the components of the vector are
* stored. The capacity of the vector is the length of this array buffer,
* and is at least large enough to contain all the vector's elements.
*
* <p>Any array elements following the last element in the Vector are null.
*
* @serial
*/
protected Object[] elementData;//对象数组
/**
* The number of valid components in this {@code Vector} object.
* Components {@code elementData[0]} through
* {@code elementData[elementCount-1]} are the actual items.
*
* @serial
*/
protected int elementCount;//对象数组长度
/**
* The amount by which the capacity of the vector is automatically
* incremented when its size becomes greater than its capacity. If
* the capacity increment is less than or equal to zero, the capacity
* of the vector is doubled each time it needs to grow.
*
* @serial
*/
protected int capacityIncrement;//向量的大小大于其容量时,容量自动增加的量。如果容量的增量小于等于零,则每次需要增大容量时,向量的容量将增大一倍。
Vector构造方法
public Vector(int initialCapacity, int capacityIncrement) {
super();
if (initialCapacity < 0)//初始容量<0,抛异常
throw new IllegalArgumentException("Illegal Capacity: "+
initialCapacity);
this.elementData = new Object[initialCapacity];//new一个容量为initialCapacity的对象数组
this.capacityIncrement = capacityIncrement;//设置capacityIncrement,如果capacityIncrement 不为0,扩容时候每次增加capacityIncrement
}
/**
* Constructs an empty vector with the specified initial capacity and
* with its capacity increment equal to zero.
*
* @param initialCapacity the initial capacity of the vector
* @throws IllegalArgumentException if the specified initial capacity
* is negative
*/
public Vector(int initialCapacity) {
this(initialCapacity, 0);//capacityIncrement默认为0
}
/**
* Constructs an empty vector so that its internal data array
* has size {@code 10} and its standard capacity increment is
* zero.
*/
public Vector() {
this(10);//initialCapacity为10
}
然后add、remove和ArrayList几乎一模一样,
区别只在于扩容部分
以下为Vector扩容部分源码
private void grow(int minCapacity) {
// overflow-conscious code
int oldCapacity = elementData.length;//计算旧对象数组长度
int newCapacity = oldCapacity + ((capacityIncrement > 0) ?
capacityIncrement : oldCapacity);//如果直到增长量,那么增长量为capacityIncrement ,否则扩容为原来的2倍
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity);
elementData = Arrays.copyOf(elementData, newCapacity);
}
对比ArrayList扩容源码
private void grow(int minCapacity) {
// overflow-conscious code
int oldCapacity = elementData.length;//当前容量
int newCapacity = oldCapacity + (oldCapacity >> 1);//新容量增加原来的0.5
if (newCapacity - minCapacity < 0)//取newCapacity 和minCapacity的大者
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);//拷扩展数组容量为newCapacity,并将赋值为当前数组elementData
}
因此Vector可以设置自动增长容量,如果不设置自动增长容量,扩容后容量为原来的2倍,而ArrayList扩容后的容量为原来的1.5倍,因此Vector更占用空间
只是加了synchronized,因此Vector是线程安全的,因此性能不如ArrayList