Collection探究之Vector

Vector与ArrayList一样内部是由数组组成的,它也是一个动态数组,但是由于其内部实现了线程安全机制,所以在性能方面较差,使用的次数也没有ArrayList那样频繁,下面我们来看一看Vector的源码。

1.Vector的定义

public class Vector<E>
    extends AbstractList<E>
    implements List<E>, RandomAccess, Cloneable, java.io.Serializable

与ArrayList一样,Vector继承了AbstractList,实现了List,RandomAccess,Cloneable与Serializable接口,所以它有着与ArrayList一样的功能。

2.Vector的属性

//Vector中用于保存数据的数组
protected Object[] elementData;
//Vector中数据的总量,也就是实际存储的数据的数量
protected int elementCount;
//Vector数组每次扩容时容器的增长量
protected int capacityIncrement;

3.Vector的构造函数

Vector 有四个构造函数,分别如下:

    //该构造函数指定了Vector容器的初始大小和每次扩容时容器增长量
    public Vector(int initialCapacity, int   capacityIncrement) {
        super();
        if (initialCapacity < 0)
            throw new IllegalArgumentException("Illegal Capacity: "+
                                               initialCapacity);
        //可以看到该构造函数在初始化时新建了一个大小为 initialCapacity的数组,并为capacityIncrement赋值
        this.elementData = new Object[initialCapacity];
        this.capacityIncrement = capacityIncrement;
    }

   //只指定容器初始化大小
    public Vector(int initialCapacity) {
        this(initialCapacity, 0);
    }

  //默认初始化函数,用于构造容器大小为10的Vector
    public Vector() {
        this(10);
    }

    //参数为集合,用于生成一个新的Vector集合
    public Vector(Collection<? extends E> c) {
    //将集合c中的元素转换成为Vector中的数组元素
        elementData = c.toArray();
        //设置实际元素数量值
        elementCount = elementData.length;
        若elementData不为Object类型的数组,则将其转换成为Object类型的数组
        if (elementData.getClass() != Object[].class)
            elementData = Arrays.copyOf(elementData, elementCount, Object[].class);
    }

4.Vector常用操作方法

4.1获取元素

//可以看到Vector中的方法都添加了synchronized关键字,因此它是线程同步的。
public synchronized E get(int index) {
        //查看输入的下标是否越界
        if (index >= elementCount)
            throw new ArrayIndexOutOfBoundsException(index);
        //这里获取元素的功能由elementData方法完成
        return elementData(index);
    }

//由于Vector本质就是数组,因此可以使用下标获取元素,返回elementData中下标为index的元素
E elementData(int index) {
        return (E) elementData[index];
    }

4.2添加元素


public synchronized boolean add(E e) {
        modCount++;
        //添加元素时,先对数组进行扩容
        ensureCapacityHelper(elementCount + 1);
        elementData[elementCount++] = e;
        return true;
    }

//这是一个私有的内部方法
 private void ensureCapacityHelper(int minCapacity) {
        //检查是否越界,若没有则让grow进行扩容
        if (minCapacity - elementData.length > 0)
            grow(minCapacity);
    }

//设置Vector数组的最大长度
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;

    private void grow(int minCapacity) {
       //获取没扩容前数组的长度
        int oldCapacity = elementData.length;
        //扩容后的Vector数组大小,若capacityIncrement大于0,则在原数组长度上增加capacityIncrement长度,若capacityIncrement小于0,则在原数组的长度基础上扩容一倍
        int newCapacity = oldCapacity + ((capacityIncrement > 0) ? capacityIncrement : oldCapacity);
        //对扩容结果进行校验,minCapacity表示当前新数组所需的最小Vector数组长度
        if (newCapacity - minCapacity < 0)
            newCapacity = minCapacity;
        //若newCapacity超过了数组的最大容量,则由hugeCapacity构建
        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;
    }

//set方法为对Index下标的元素进行覆盖
  public synchronized void setElementAt(E obj, int index) {
        if (index >= elementCount) {
            throw new ArrayIndexOutOfBoundsException(index + " >= " +
                                                     elementCount);
        }
        elementData[index] = obj;
    }

//直接将元素添加到Vector数组的末尾
public synchronized void addElement(E obj) {
        modCount++;
        ensureCapacityHelper(elementCount + 1);
        elementData[elementCount++] = obj;
    }

  //向Vector容器中批量添加元素
   public synchronized boolean addAll(Collection<? extends E> c) {
        modCount++;
        //先将c容器中的元素转换成为object类型的数组
        Object[] a = c.toArray();
        int numNew = a.length;
        //对Vector数组进行扩容
        ensureCapacityHelper(elementCount + numNew);
        //将c容器中的元素复制到Vector中
        System.arraycopy(a, 0, elementData, elementCount, numNew);
        //修改实际元素数量
        elementCount += numNew;
        return numNew != 0;
    }

//与上面的addAll方法差不多,只不过该方法是在Vector指定位置Index处添加集合C的元素
public synchronized boolean addAll(int index, Collection<? extends E> c) {
        modCount++;
        //检查是否越界
        if (index < 0 || index > elementCount)
            throw new ArrayIndexOutOfBoundsException(index);

        Object[] a = c.toArray();
        int numNew = a.length;
        ensureCapacityHelper(elementCount + numNew);
        //numMoved为需要移动元素的个数
        int numMoved = elementCount - index;
        if (numMoved > 0)
            //将原先Index处的numMoved个元素,向后移动到距离原位置numNew处
            System.arraycopy(elementData, index, elementData, index + numNew,numMoved);

        System.arraycopy(a, 0, elementData, index, numNew);
        elementCount += numNew;
        return numNew != 0;

4.3删除元素

//用于移除Vector中的obj元素
public synchronized boolean removeElement(Object obj) {
        modCount++;
        //先用indexOf找到第一个值为obj元素的下标位置
        int i = indexOf(obj);
        if (i >= 0) {
            //移除该下标
            removeElementAt(i);
            return true;
        }
        return false;
    }

 public int indexOf(Object o) {
        return indexOf(o, 0);
    }
//该方法用于移除元素值为o的元素
public synchronized int indexOf(Object o, int index) {
        //Vector是允许元素值为null的
        if (o == null) {
            //从index开始向后进行遍历,找到第一个元素值为null的下标
            for (int i = index ; i < elementCount ; i++)
                if (elementData[i]==null)
                    return i;
        } else {
        //从index开始向后进行遍历,找到第一个元素值为o的下标
            for (int i = index ; i < elementCount ; i++)
                if (o.equals(elementData[i]))
                    return i;
        }
        return -1;
    }

//该方法用于移除Vector中的所有元素
 public synchronized void removeAllElements() {
        modCount++;
        // Let gc do its work
        for (int i = 0; i < elementCount; i++)
            elementData[i] = null;

        elementCount = 0;
    }

//移除指定位置index处的元素
public synchronized E remove(int index) {
        modCount++;
        if (index >= elementCount)
            throw new ArrayIndexOutOfBoundsException(index);
        //获取原先index处的值
        E oldValue = elementData(index);
        //需要移动的距离
        int numMoved = elementCount - index - 1;
        if (numMoved > 0)
            System.arraycopy(elementData, index+1, elementData, index,numMoved);
        elementData[--elementCount] = null; 
        return oldValue;
    }

5一般常用方法

//该方法用于对Vector数组进行扩容
public synchronized void setSize(int newSize) {
        modCount++;
        //若新容器大小大于实际元素值,则扩容
        if (newSize > elementCount) {
            ensureCapacityHelper(newSize);
        } else {
        //若小于,则将Vector后elementCount-newSize个元素删除
            for (int i = newSize ; i < elementCount ; i++) {

                elementData[i] = null;
            }
        }
        elementCount = newSize;
    }

//返回Vector容器中实际元素个数
   public synchronized int size() {
        return elementCount;
    }

   //判断Vector容器是否为空
 public synchronized boolean isEmpty() {
        return elementCount == 0;
    }

//返回所有的元素
 public Enumeration<E> elements() {
         //匿名函数
        return new Enumeration<E>() {
            int count = 0;
            //是否还有元素
            public boolean hasMoreElements() {
                return count < elementCount;
            }

            //返回元素
            public E nextElement() {
                synchronized (Vector.this) {
                    if (count < elementCount) {
                        return elementData(count++);
                    }
                }
                throw new NoSuchElementException("Vector Enumeration");
            }
        };
    }

//检查Vector中是否包含o对象
public boolean contains(Object o) {
        return indexOf(o, 0) >= 0;
    }

Vector就分析那么多, 一般情况下Vector使用的频率不是很高,所以要记住它与ArrayList的区别即可。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值