JDK源码解析---Vector

1.概述

Vector的内部实现类似于ArrayList,Vector也是基于一个容量能够动态增长的数组来实现的,该类是JDK1.0版本添加的类,它的很多实现方法都加入了同步语句,因此是线程安全的。

2.类图

在这里插入图片描述

继承了AbstractList

实现了List接口,一些基本的List操作的实现

实现了RandomAccess接口,表示他支持快速随机访问。

实现了Cloneable接口

实现了序列化接口

3.属性

protected Object[] elementData;// 用于存储元素的数组。

protected int elementCount;// 数组中元素的个数

protected int capacityIncrement;// 扩容增加的容量,当前元素个数将要大于最大容量的时候,会根据这个值来扩容。若这个值是0,则进行2倍扩容

private static final long serialVersionUID = -2767605614048989439L;//序列化id

4.构造方法

一共有4个构造方法

  • Vector(int initialCapacity, int capacityIncrement)

    根据初始化容量initialCapacity构建一个数组,设置扩容增加的大小

    public Vector(int initialCapacity, int capacityIncrement) {
          
          
        super();
        if (initialCapacity < 0)
            throw new IllegalArgumentException("Illegal Capacity: "+
                                               initialCapacity);
        this.elementData = new Object[initialCapacity];
        this.capacityIncrement = capacityIncrement;
    }
    
  • Vector(int initialCapacity)

    指定初始容量的数组,capacityIncrement等于0,所以扩容的时候进行两倍扩容

    public Vector(int initialCapacity) {
          
          
        this(initialCapacity, 0);
    }
    
  • Vector()

    无参构造函数

    初始容量为10,扩容的时候两倍扩容。

    public Vector() {
          
          
        this(10);
    }
    
  • Vector(Collection<? extends E> c)

    将集合c中的元素转换成数组直接赋值给elementData

    设置元素个数elementCount。若当前数组的类型不是Object,则执行拷贝,转变成Object类型的数组。

    public Vector(Collection<? extends E> c) {
          
          
        elementData = c.toArray();
        elementCount = elementData.length;
        // c.toArray might (incorrectly) not return Object[] (see 6260652)
        if (elementData.getClass() != Object[].class)
            elementData = Arrays.copyOf(elementData, elementCount, Object[].class);
    }
    

5.方法介绍

5.1 copyInto

将anArray数组拷贝给Vector中的elementData。

public synchronized void copyInto(Object[] anArray) {
    
    
    System.arraycopy(elementData, 0, anArray, 0, elementCount);
}

5.2 trimToSize

缩容,当前数组中元素的个数小于数组长度的时候,进行缩容。拷贝一份新的数组,长度为当前数组元素的个数。

public synchronized void trimToSize() {
    
    
    modCount++;
    int oldCapacity = elementData.length;
    if (elementCount < oldCapacity) {
    
    
        elementData = Arrays.copyOf(elementData, elementCount);
    }
}

5.3 ensureCapacity

扩容,真正的执行逻辑在grow,先根据当前数组的大小和capacityIncrement计算出新的数组大小。然后和minCapacity比较。若小于minCapacity,则新的数组大小改为minCapacity。原则就是往大了的扩。若新的数组大小超过了最大定义的容量上限,则将新容量设为Integer.MAX_VALUE。

public synchronized void ensureCapacity(int minCapacity) {
    
    
    if (minCapacity > 0) {
    
    
        modCount++;
        ensureCapacityHelper(minCapacity);
    }
}
private void ensureCapacityHelper(int minCapacity) {
    
    
    // overflow-conscious code
    if (minCapacity - elementData.length > 0)
        grow(minCapacity);
}
private void grow(int minCapacity) {
    
    
    // overflow-conscious code
    int oldCapacity = elementData.length;//当前数组的大小
    int newCapacity = oldCapacity + ((capacityIncrement > 0) ?
                                     capacityIncrement : oldCapacity);//新的容量根据capacityIncrement来计算,若capacityIncrement大于0,则新的容量等于当前数组的大小+capacityIncrement。否则就是两倍的当前数组的大小。
    if (newCapacity - minCapacity < 0)//若给定的参数minCapacity小于计算出来的新容量。则将新容量改为minCapacity。
        newCapacity = minCapacity;
    if (newCapacity - MAX_ARRAY_SIZE > 0)// 如果新容量大于最大数组大小则返回Integer.MAX_VALUE作为新的容量。
        newCapacity = hugeCapacity(minCapacity);
    elementData = Arrays.copyOf(elementData, newCapacity);
}

5.4 setSize

参数newSize若大于当前元素的个数,则执行扩容。

若小于当前元素的个数,则将newSize之后的元素都设置为null。

public synchronized void setSize(int newSize) {
    
    
    modCount++;
    if (newSize > elementCount) {
    
    
        ensureCapacityHelper(newSize);
    } else {
    
    
        for (int i = newSize ; i < elementCount ; i++) {
    
    
            elementData[i] = null;
        }
    }
    elementCount = newSize;
}

5.5 capacity

返回数组的容量

public synchronized int capacity() {
    
    
    return elementData.length;
}

5.6 size

返回数组中元素的个数

public synchronized int size() {
    
    
    return elementCount;
}

5.7 isEmpty

判断是否为空

public synchronized boolean isEmpty() {
    
    
    return elementCount == 0;
}

5.8 elements

返回一个枚举器。用来枚举Vector中的元素

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");
        }
    };
}

5.9 contains

判断是否包含元素o,遍历数组去寻找o。

public boolean contains(Object o) {
    
    
    return indexOf(o, 0) >= 0;
}
public int indexOf(Object o) {
    
    
    return indexOf(o, 0);
}
public synchronized int indexOf(Object o, int index) {
    
    
    if (o == null) {
    
    
        for (int i = index ; i < elementCount ; i++)
            if (elementData[i]==null)
                return i;
    } else {
    
    
        for (int i = index ; i < elementCount ; i++)
            if (o.equals(elementData[i]))
                return i;
    }
    return -1;
}

5.10 lastIndexOf

从后往前找

public synchronized int lastIndexOf(Object o) {
    
    
    return lastIndexOf(o, elementCount-1);
}
public synchronized int lastIndexOf(Object o, int index) {
    
    
    if (index >= elementCount)
        throw new IndexOutOfBoundsException(index + " >= "+ elementCount);

    if (o == null) {
    
    
        for (int i = index; i >= 0; i--)
            if (elementData[i]==null)
                return i;
    } else {
    
    
        for (int i = index; i >= 0; i--)
            if (o.equals(elementData[i]))
                return i;
    }
    return -1;
}

5.11 elementAt

返回数组中下标为index的值

public synchronized E elementAt(int index) {
    
    
    if (index >= elementCount) {
    
    
        throw new ArrayIndexOutOfBoundsException(index + " >= " + elementCount);
    }

    return elementData(index);
}
E elementData(int index) {
    
    
    return (E) elementData[index];
}

5.12 firstElement

返回第一个元素

public synchronized E firstElement() {
    
    
    if (elementCount == 0) {
    
    
        throw new NoSuchElementException();
    }
    return elementData(0);
}

5.12 lastElement

返回最后一个元素

public synchronized E lastElement() {
    
    
    if (elementCount == 0) {
    
    
        throw new NoSuchElementException();
    }
    return elementData(elementCount - 1);
}

5.13 setElementAt

设置数组中下标为index的元素为obj

public synchronized void setElementAt(E obj, int index) {
    
    
    if (index >= elementCount) {
    
    
        throw new ArrayIndexOutOfBoundsException(index + " >= " +
                                                 elementCount);
    }
    elementData[index] = obj;
}

5.14 remove & removeElementAt

移除下标为index的元素

index+1之后的元素拷贝到index开始的位置。然后将最后一个元素设为null。

public synchronized void removeElementAt(int index) {
    
    
    modCount++;
    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 */
}

会返回旧值。

public synchronized E remove(int index) {
    
    
    modCount++;
    if (index >= elementCount)
        throw new ArrayIndexOutOfBoundsException(index);
    E oldValue = elementData(index);

    int numMoved = elementCount - index - 1;
    if (numMoved > 0)
        System.arraycopy(elementData, index+1, elementData, index,
                         numMoved);
    elementData[--elementCount] = null; // Let gc do its work

    return oldValue;
}

5.15 add & insertElementAt

public void add(int index, E element) {
    
    
    insertElementAt(element, index);
}

先执行扩容的逻辑,避免放不下。然后执行拷贝 将index开始之后的元素拷贝到index+1的位置。然后将下标为index处设置为obj。

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++;
}

5.16 add & addElement

在数组末尾添加元素obj。

public synchronized boolean add(E e) {
    
    
    modCount++;
    ensureCapacityHelper(elementCount + 1);
    elementData[elementCount++] = e;
    return true;
}
public synchronized void addElement(E obj) {
    
    
    modCount++;
    ensureCapacityHelper(elementCount + 1);
    elementData[elementCount++] = obj;
}

5.17 remove

移除元素obj,先找到obj的位置,若找到了执行removeElementAt(i);返回true 否则返回false。

public boolean remove(Object o) {
    
    
    return removeElement(o);
}
public synchronized boolean removeElement(Object obj) {
    
    
    modCount++;
    int i = indexOf(obj);
    if (i >= 0) {
    
    
        removeElementAt(i);
        return true;
    }
    return false;
}

5.18 clear & removeAllElements

移除所有的元素,遍历数组 全部设为null。设置elementCount为0

public void clear() {
    
    
    removeAllElements();
}
public synchronized void removeAllElements() {
    modCount++;
    // Let gc do its work
    for (int i = 0; i < elementCount; i++)
        elementData[i] = null;

    elementCount = 0;
}

5.19 clone

重写了父类Object的clone

调用父类的clone,然后将里面的数组拷贝一份给elementData,设置修改次数为0.

public synchronized Object clone() {
    
    
    try {
    
    
        @SuppressWarnings("unchecked")
            Vector<E> v = (Vector<E>) super.clone();
        v.elementData = Arrays.copyOf(elementData, elementCount);
        v.modCount = 0;
        return v;
    } catch (CloneNotSupportedException e) {
    
    
        // this shouldn't happen, since we are Cloneable
        throw new InternalError(e);
    }
}

5.20 toArray

返回的是数组的拷贝对象

public synchronized Object[] toArray() {
    return Arrays.copyOf(elementData, elementCount);
}

将数组拷贝给数组a

public synchronized <T> T[] toArray(T[] a) {
    
    
    if (a.length < elementCount)
        return (T[]) Arrays.copyOf(elementData, elementCount, a.getClass());

    System.arraycopy(elementData, 0, a, 0, elementCount);

    if (a.length > elementCount)
        a[elementCount] = null;

    return a;
}

5.21 get

获取下标为index的元素

public synchronized E get(int index) {
    
    
    if (index >= elementCount)
        throw new ArrayIndexOutOfBoundsException(index);

    return elementData(index);
}

5.22 set

设置下标为index的元素。

public synchronized E set(int index, E element) {
    
    
    if (index >= elementCount)
        throw new ArrayIndexOutOfBoundsException(index);

    E oldValue = elementData(index);
    elementData[index] = element;
    return oldValue;
}

猜你喜欢

转载自blog.csdn.net/gongsenlin341/article/details/108602846