0
点赞
收藏
分享

微信扫一扫

JDK源码util包分析——Vector源码(13)

半夜放水 2022-03-12 阅读 52
java

Vector源码分析

Vector的结构图

在这里插入图片描述

Vector的概述

Vector 是矢量队列,它是JDK1.0版本添加的类。继承于AbstractList,实现了List, RandomAccess, Cloneable这些接口。
Vector 继承了AbstractList,实现了List;所以,它是一个队列,支持相关的添加、删除、修改、遍历等功能。
Vector 实现了RandmoAccess接口,即提供了随机访问功能。RandmoAccess是java中用来被List实现,为List提供快速访问功能的。在Vector中,我们即可以通过元素的序号快速获取元素对象;这就是快速随机访问。
Vector 实现了Cloneable接口,即实现clone()函数。它能被克隆。
和ArrayList不同,Vector中的操作是线程安全的,Vector的线程安全通过在方法上直接加synchronized实现。扩容默认扩大为原来的2倍。

Vector的属性

// Object类型的数组
// 注意:访问修饰符有所不同,Vector用protected修饰,而ArrayList用private修饰。
// JavaSe中:private变量只能被当前类的方法访问,而protected可以被同一包中的所有类和其他包的子类访问
protected Object[] elementData;

// 动态数组的实际有效大小,即数组中存储的元素个数
protected int elementCount;
    
// 动态数组的增长系数:若开始事先没有指定,则默认是增加一倍的大小
protected int capacityIncrement;
   
// 序列版本号
private static final long serialVersionUID = -2767605614048989439L;

Vector的构造方法

// 默认空参构造函数
public Vector() {
    // 调用指定初始容量的构造函数,初始容量为10
    this(10);
}

// 可以指定初始容量的构造函数
public Vector(int initialCapacity) {
    // 调用指定初始容量和增长系数的构造函数,增长系数设置为0
    this(initialCapacity, 0);
}

// 可以指定初始容量和增长系数的构造函数
public Vector(int initialCapacity, int capacityIncrement) {
    super();
    if (initialCapacity < 0)
        throw new IllegalArgumentException("Illegal Capacity: "+
                                           initialCapacity);
    // 根据初始容量创建一个Object类型的数组
    this.elementData = new Object[initialCapacity];
    // 给增长系数赋值
    this.capacityIncrement = capacityIncrement;
}

// 参数为集合类型的构造函数
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)
        // 将参数集合c 中的数据拷贝到elementData
        elementData = Arrays.copyOf(elementData, elementCount, Object[].class);
}

Vector的方法

get方法

// 获得指定下标的元素数据
public synchronized E get(int index) {
    if (index >= elementCount)
        throw new ArrayIndexOutOfBoundsException(index);
    return elementData(index);
}

@SuppressWarnings("unchecked")
E elementData(int index) {
    return (E) elementData[index];
}

set方法

// 修改指定下标的元素数据
public synchronized E set(int index, E element) {
    if (index >= elementCount)
        throw new ArrayIndexOutOfBoundsException(index);
    E oldValue = elementData(index);
    elementData[index] = element;
    return oldValue;
}

remove方法

// 删除某个元素数据
public boolean remove(Object o) {
    return removeElement(o);
}

// 删除obj
public synchronized boolean removeElement(Object obj) {
    modCount++;
    // 找到指定元素的下标
    int i = indexOf(obj);//调用indexOf找到指定位置,在下方
    if (i >= 0) {
        // 根据下标删除元素
        removeElementAt(i);
        return true;
    }
    return false;
}

// 根据下标删除元素
public synchronized void removeElementAt(int index) {
    modCount++;
    if (index >= elementCount) {
        throw new ArrayIndexOutOfBoundsException(index + " >= " +
                                                 elementCount);
    }
    else if (index < 0) {
        throw new ArrayIndexOutOfBoundsException(index);
    }
    // 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 int indexOf(Object o) {
        return indexOf(o, 0);
    }
//从index开始寻找o,返回o第一次出现的索引
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;
    }

add方法

// 在数组末尾添加指定元素
public synchronized boolean add(E e) {
    modCount++;
    // 判断是否需要扩容
    ensureCapacityHelper(elementCount + 1);//该方法将会在扩容部分讲解
    elementData[elementCount++] = e;
    return true;
}

element相关的方法

//将指定的组件添加到此向量的末尾,将其大小增加 1。如果向量的大小比容量大,则增大其容量。
   public synchronized void addElement(E obj) {
        modCount++;
        ensureCapacityHelper(elementCount + 1);
        elementData[elementCount++] = obj;
    }
//返回指定索引处的组件。 其实这个方法就是和我们之前使用的get方法很相似。源码很简单,就是说先进行一个index的有效位检验,如果正确在进入elementData(int index)方法,直接取数组的数据。
 public synchronized E elementAt(int index) {
        if (index >= elementCount) {
            throw new ArrayIndexOutOfBoundsException(index + " >= " + elementCount);
        }

        return elementData(index);
    }
//返回此向量的组件的枚举。返回的 Enumeration 对象将生成此向量中的所有项。生成的第一项为索引 0 处的项,然后是索引 1 处的项,依此类推。这个和遍历时候用的Iterator很相似。
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");
            }
        };
    }

element相关的方法与之前的add,get方法相似,还有的就不在这列出,可自行观看源码。

其他方法

// 将数组Vector中的全部元素都拷贝到数组anArray中去,调用本地方法arraycopy
public synchronized void copyInto(Object[] anArray) {
    System.arraycopy(elementData, 0, anArray, 0, elementCount);
}
//将集合的容量修剪为集合的当前大小
public synchronized void trimToSize() {
    modCount++;
    int oldCapacity = elementData.length;
    if (elementCount < oldCapacity) {
        elementData = Arrays.copyOf(elementData, elementCount);
    }
}

// 设置Vector数组的大小
public synchronized void setSize(int newSize) {
    // 修改次数++
    modCount++;
    // 判断设置的数组大小是否大于Vector中存储的有效元素的个数
    // 若 newSize > Vector中有存储的效元素的个数,则调整Vector的大小
    if (newSize > elementCount) {
        // 调用判断是否扩容的方法,如果需要扩容则该方法内部调用扩容方法grow()
        ensureCapacityHelper(newSize);
    } else {
        // 如果上述判断不成立,则将newSize位置之后开始的元素都设置为null
        for (int i = newSize ; i < elementCount ; i++) {
            elementData[i] = null;
        }
    }
    
    // 更新有效元素个数
    elementCount = newSize;
}

// 获取Vector的当前容量
public synchronized int capacity() {
    return elementData.length;
}

// 获取Vector里面的有效元素个数
public synchronized int size() {
    return elementCount;
}

// 判断Vecotor中是否包含元素 o
public boolean contains(Object o) {
    return indexOf(o, 0) >= 0;
}
......

扩容方法(重要)

// 确定数组当前的容量大小
public synchronized void ensureCapacity(int minCapacity) {
    if (minCapacity > 0) {
        modCount++;
        ensureCapacityHelper(minCapacity);
    }
}

// 如果:当前容量 > 当前数组长度,就调用grow(minCapacity)方法进行扩容
// 由于该方法是在ensureCapacity()中被调用的,而ensureCapacity()方法中已经加上了synchronized锁,所以
// 该方法不需要再加锁
private void ensureCapacityHelper(int minCapacity) {
    // overflow-conscious code
    if (minCapacity - elementData.length > 0)
        grow(minCapacity);
}

// 最大上限的数组容量大小
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE 
    
// Vector集合中的核心扩容方法
private void grow(int minCapacity) {
    // overflow-conscious code
    // 获取旧数组的容量
    int oldCapacity = elementData.length;
    // 得到扩容后(如果需要扩容的话)的新数组容量
    int newCapacity = oldCapacity + ((capacityIncrement > 0) ?
                                      capacityIncrement : oldCapacity);//可自定义扩容大小,默认为2倍(oldCapacity + oldCapacity)
    // 如果新容量 < 数组实际所需容量,则令newCapacity = minCapacity
    if (newCapacity - minCapacity < 0)
         newCapacity = minCapacity;
    // 如果当前所需容量 > MAX_ARRAY_SIZE,则新容量设为 Integer.MAX_VALUE,否则设为 MAX_ARRAY_SIZE
    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;
}

举报

相关推荐

0 条评论