Vector源码解析
老样子,话不多说先上一张UML类图
- Vector的初始化构造方法
无参构造(默认调用初始化容量的构造方法,默认容量为10)
public Vector() {//这里会调用Vector带容量参数的构造方法默认容量为10//这里和ArrayList不同的是ArrayList在调用add方法才初始化容量 this(10);}
指定初始化容量大小
public Vector(int initialCapacity) {//这里调用下面指定初始化容量和增长系数的构造方法,默认增长系数为0 this(initialCapacity, 0);}
指定初始化容量和增长系数
public Vector(int initialCapacity, int capacityIncrement) { super(); //容量不能小于0 if (initialCapacity < 0) throw new IllegalArgumentException("Illegal Capacity: "+ initialCapacity); //为对象数组指定初始化容量 this.elementData = new Object[initialCapacity]; //设置增长系数 this.capacityIncrement = capacityIncrement;}
使用另外一个集合构造该集合
public Vector(Collection extends E> c) {//将传入集合转成数组 elementData = c.toArray(); //Vector的元素个数就是集合的长度 elementCount = elementData.length; // c.toArray might (incorrectly) not return Object[] (see 6260652) //判断添加进的元素对象是否为对象数组类型 if (elementData.getClass() != Object[].class) //进行浅拷贝将类型转化为对象数组 elementData = Arrays.copyOf(elementData, elementCount, Object[].class);}
- add(E e)方法
public synchronized boolean add(E e) {//更新操作次数 modCount++; //确保可以保存元素的容量,如有必要会进行扩容 ensureCapacityHelper(elementCount + 1); elementData[elementCount++] = e; return true;}//如有必要,增加当前数组的容量,以确保至少可以保存minCapacity容量参数指定的元素个数private void ensureCapacityHelper(int minCapacity) { // overflow-conscious code if (minCapacity - elementData.length > 0) //Vector的扩容方法 grow(minCapacity);}//扩容方法private void grow(int minCapacity) { // overflow-conscious code //原Vector容量值 int oldCapacity = elementData.length; //如果有给capacityIncrement设置增长系数的话,就加上该系数值来扩容,否则将原先的数组容量变为2*oldCapacity int newCapacity = oldCapacity + ((capacityIncrement > 0) ? capacityIncrement : oldCapacity); //如果重新的设置的容量值还要小于最小要求的容量值得话 if (newCapacity - minCapacity < 0) //就将最小的容量值赋值给新的容量 newCapacity = minCapacity; //如果新容量值比限制的最大容量还要大的话 if (newCapacity - MAX_ARRAY_SIZE > 0) //重新设置大小 newCapacity = hugeCapacity(minCapacity); //将原先数组的元素浅拷贝到一个新的数组 elementData = Arrays.copyOf(elementData, newCapacity);}//获取最大容量private static int hugeCapacity(int minCapacity) { if (minCapacity < 0) // overflow throw new OutOfMemoryError(); return (minCapacity > MAX_ARRAY_SIZE) ? Integer.MAX_VALUE : MAX_ARRAY_SIZE;}
add(int index, E element)方法(指定位置添加元素)
public void add(int index, E element) { insertElementAt(element, index);}public synchronized void insertElementAt(E obj, int index) { modCount++; if (index > elementCount) { throw new ArrayIndexOutOfBoundsException(index + " > " + elementCount); } //如上确保容量 ensureCapacityHelper(elementCount + 1); //将指定索引到末尾的元素分别往左移动一位 System.arraycopy(elementData, index, elementData, index + 1, elementCount - index); elementData[index] = obj; elementCount++;}
addAll(Collection extends E> c)方法
public synchronized boolean addAll(Collection extends E> c) {//更新操作次数 modCount++; //将传入的集合转为数组 Object[] a = c.toArray(); //获取传入集合的长度 int numNew = a.length; //如上确保容量 ensureCapacityHelper(elementCount + numNew); //将指定索引到末尾的元素分别往左移动一位 System.arraycopy(a, 0, elementData, elementCount, numNew); //集合的大小为旧集合的大小+新集合的大小 elementCount += numNew; return numNew != 0;}
- remove(int index)方法
public synchronized E remove(int index) { modCount++; //对index进行边界检查 if (index >= elementCount) throw new ArrayIndexOutOfBoundsException(index); //获取要删除坐标的元素 E oldValue = elementData(index); //计算指定索引与末尾元素的个数 int numMoved = elementCount - index - 1; //如果个数大于0 if (numMoved > 0) //将指定索引到末尾的元素分别往左移动一位 System.arraycopy(elementData, index+1, elementData, index, numMoved); //递减元素个数,并将末尾元素置空 elementData[--elementCount] = null; // Let gc do its work return oldValue;}
remove(Object o)方法
public boolean remove(Object o) {//调用removeElement(Object obj)方法 return removeElement(o);}public synchronized boolean removeElement(Object obj) {//更新操作次数 modCount++; //得到要删除元素的坐标 int i = indexOf(obj); if (i >= 0) { //根据坐标删除元素 removeElementAt(i); return true; } return false;}public synchronized void removeElementAt(int index) { modCount++; //对index进行边界检查 if (index >= elementCount) { throw new ArrayIndexOutOfBoundsException(index + " >= " + elementCount); } else if (index < 0) { throw new ArrayIndexOutOfBoundsException(index); } //计算指定索引与末尾元素的个数 int j = elementCount - index - 1; if (j > 0) { //将指定索引到末尾的元素分别往左移动一位 System.arraycopy(elementData, index + 1, elementData, index, j); } //减少集合容量 elementCount--; //递减元素个数,并将末尾元素置空 elementData[elementCount] = null; /* to let gc do its work */}
removeAll(Collection> c)方法
//删除指定集合中的所有元素public synchronized boolean removeAll(Collection> c) {//调用AbstractCollection中的removeAll的方法 return super.removeAll(c);}
retainAll(Collection> c)方法
//删除非集合c中的元素public synchronized boolean retainAll(Collection> c) { return super.retainAll(c);}
clear()方法
public void clear() {//清空集合方法调用上面removeAllElements方法 removeAllElements();}
- get(int index)方法
public synchronized E get(int index) {//对index进行边界检查 if (index >= elementCount) throw new ArrayIndexOutOfBoundsException(index);//根据下标获取元素 return elementData(index);}E elementData(int index) {//在数组中根据下标获取元素 return (E) elementData[index];}
- set(int index, E element)方法
public synchronized E set(int index, E element) {//对index进行边界检查 if (index >= elementCount) throw new ArrayIndexOutOfBoundsException(index);//获取index坐标的元素 E oldValue = elementData(index); //将set的元素放入数组指定下标 elementData[index] = element; return oldValue;}
总结:
- Vector是使用数组保存数据,和ArrayList一样
- 在无参的构造方法中,默认的初始容量为10,增长系数为0比ArrayList多了一个增长系数的概念
- Vector类是线程安全的List,其底层是通过Synchronized关键字实现的(同步方法),ArrayList是线程不安全的
- 扩容机制:如果增长系数不位 0 那么就是当前容量 + 增长系数,否则就是2倍,ArrayList为1.5倍左右