Vector源码解析(jdk1.8)

Posted yuminfeng728

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Vector源码解析(jdk1.8)相关的知识,希望对你有一定的参考价值。

概述

Vector实现了List的接口,底层同样是基于数组实现的,可以存储null。功能结构与ArrayList的类似,不同的是线程安全的。

构造函数

protected Object[] elementData;

protected int capacityIncrement;

public Vector() 
    this(10);


public Vector(int initialCapacity) 
    this(initialCapacity, 0);


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

构造函数中,初始化了存储元素的数组elementData和容量增量的值。

添加元素add/addAll

Vector使用add来添加元素:

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


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);
    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直接添加元素的时候,首先通过ensureCapacityHelper来确认存储元素的数组的容量时候足够。如果不够,则进行grow扩容,增量大小为:(容量增量*数组长度)。确认完容量之后,直接将元素添加到数组后面。

Vector还提供了在指定位置上添加元素:

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

首先判断index的合法性,然后通过System.arraycopy将元素插入到指定的位置中。

删除元素remove/removeAll

Vector使用remove来删除元素:

public boolean remove(Object o) 
    return removeElement(o);


public synchronized boolean removeElement(Object obj) 
    modCount++;
    int i = indexOf(obj); //获取当前对象的索引值index
    if (i >= 0) 
        removeElementAt(i);
        return true;
    
    return false;


public int indexOf(Object o) 
    return indexOf(o, 0);


//存在该对象时,返回当前索引值,否则返回-1
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;


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;

    //删除对应index位置上的元素
    if (j > 0) 
        System.arraycopy(elementData, index + 1, elementData, index, j);
    
    elementCount--;
    elementData[elementCount] = null; /* to let gc do its work */

Vector使用removeAll来删除元素:

public synchronized boolean removeAll(Collection<?> c) 
    return super.removeAll(c);

调用父类的方法,AbstractCollection中removeAll:

public boolean removeAll(Collection<?> c) 
    Objects.requireNonNull(c);
    boolean modified = false;
    Iterator<?> it = iterator();
    while (it.hasNext()) 
        if (c.contains(it.next())) 
            it.remove();
            modified = true;
        
    
    return modified;

上面分析的add/addAll/remove/removeAll等方法都是接口List提供的方法,Vector自身也提供了方法来操作元素:

//添加元素
public synchronized void addElement(E obj) 
    modCount++;
    ensureCapacityHelper(elementCount + 1);
    elementData[elementCount++] = obj;


//删除元素
public synchronized boolean removeElement(Object obj) 
    modCount++;
    int i = indexOf(obj);
    if (i >= 0) 
        removeElementAt(i);
        return true;
    
    return false;


//删除所有元素
public synchronized void removeAllElements() 
    modCount++;
    // Let gc do its work
    for (int i = 0; i < elementCount; i++)
        elementData[i] = null;

    elementCount = 0;


//清除所有元素
public void clear() 
    removeAllElements();

总结:
1. Vector与ArrayList一样,都可以动态改变数组的容量大小,可以通过索引下标来查找指定位置的值。
2. 与ArrayList最大的区别就是Vector的操作都是线程安全的,所以它的执行效率比ArrayList的低。

以上是关于Vector源码解析(jdk1.8)的主要内容,如果未能解决你的问题,请参考以下文章

JavaSE面试题——基于JDK1.8中Vector的实现原理(源码剖析)

JDK1.8源码解析-HashMap

HashMap putVal 源码解析-JDK1.8

深入LinkedHashMap源码解析(JDK1.8)

HashMap源码解析(JDK1.8)

Hashtable源码解析(JDK1.8)