Vector底层原理

简介: Vector底层原理

Vector源码分析

Vector于ArrayList类似同样是数组类型,但是是线程安全的,为什么线程安全?在增删改方法中都加上了synchronized关键字

成员变量

protected Object[] elementData;//存储ArrayList元素的临时数组
protected int elementCount;//存储元素的个数
protected int capacityIncrement;//扩容容量

构造函数

1.无参构造函数

默认初始容量10

public Vector() {
        this(10);
    }

2.有参构造函数

指定Vector的初始容量和扩容时的增长系数为0

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

指定Vector的初始容量和扩容时的增长系数大小

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数组

public Vector(Collection<? extends E> c) {
    Object[] a = c.toArray();
    elementCount = a.length;
    if (c.getClass() == ArrayList.class) {
        elementData = a;
    } else {
        elementData = Arrays.copyOf(a, elementCount, Object[].class);
    }
}

增加方法

addElement(E obj)

public synchronized void addElement(E obj) {
        modCount++;//修改数+1
        ensureCapacityHelper(elementCount + 1);
        elementData[elementCount++] = obj;//在数组中设置元素位置
    }

判断是否需要扩容

private void ensureCapacityHelper(int minCapacity) {
    //当前元素个数大于数组容量就扩容
    if (minCapacity - elementData.length > 0)
        grow(minCapacity);
}

扩容方法

private void grow(int minCapacity) {
        int oldCapacity = elementData.length;//10
        int newCapacity = oldCapacity + ((capacityIncrement > 0) ?
                                         capacityIncrement : oldCapacity);//0>0?0:10
        if (newCapacity - minCapacity < 0)
            newCapacity = minCapacity;
        if (newCapacity - MAX_ARRAY_SIZE > 0)
            newCapacity = hugeCapacity(minCapacity);
        elementData = Arrays.copyOf(elementData, newCapacity);
    }

以上代码表示,默认会创建一个10长度的数组,当第11个参数添加的时候,进入grow方法,oldCapacity=10,newCapacity=10+10=20,最后copy数组。因此Vector扩容容量为原来的两倍。

插入方法

insertElementAt(E obj, int index)方法

在指定位置插入

public synchronized void insertElementAt(E obj, int index) {
    modCount++;
    //判断下标索引是否合理
    if (index > elementCount) {
        throw new ArrayIndexOutOfBoundsException(index
                                                 + " > " + elementCount);
    }
    //判断是否需要扩容
    ensureCapacityHelper(elementCount + 1);
    //数组Copy 把当前位置留出来,index到后面的元素全部后移一个
    System.arraycopy(elementData, index, elementData, index + 1, elementCount - index);
    //插入当前元素
    elementData[index] = obj;
    //数量+1
    elementCount++;
}

删除方法

removeElementAt(int index)方法

删除指定索引位置的方法

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);
    }
    //数组容元素-1
    elementCount--;
    //最后多余的位置置为空
    elementData[elementCount] = null;
}

removeAllElements()

public synchronized void removeAllElements() {
    modCount++;//修改次数
    //遍历删除元素
    for (int i = 0; i < elementCount; i++)
        elementData[i] = null;//赋值为空
    elementCount = 0;//元素个数为0
}

其他方法

elementAt(int index)

根据索引获取元素

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

firstElement()

获取第一个元素

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

lastElement()

获取最后一个元素

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

setElementAt(E obj, int index)

根据索引位置设置元素

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

indexOf(Object o, int index)

在指定范围内查找元素索引

public synchronized int indexOf(Object o, int index) {
 //判断对象是否为空,返回-1
    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;//未匹配
}

lastIndexOf(Object o, int index)

在指定范围内倒序查找元素索引

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;
}
相关文章
|
11月前
|
存储 Cloud Native Linux
C++ vector底层实现原理
C++ vector底层实现原理
|
12月前
|
存储 编译器 C++
vector使用及简单实现【STL】【附题】
vector使用及简单实现【STL】【附题】
32 0
|
容器
库中如何实现vector
库中如何实现vector
36 0
|
5月前
|
存储 算法 编译器
【STL】vector的底层原理及其实现
【STL】vector的底层原理及其实现
|
5月前
|
存储 编译器 C++
【STL】list的底层原理及其实现
【STL】list的底层原理及其实现
|
5月前
|
消息中间件 Kubernetes NoSQL
vector相关知识点
vector相关知识点
|
12月前
|
存储 C++ 容器
【C++】STL之vector操作
【C++】STL之vector操作
|
存储 算法 测试技术
【C++ STL】vector基础知识
本篇将学习vector的基础知识
73 0
|
存储 算法 C++
【C++】STL —— vector基本使用
【C++】STL —— vector基本使用
148 0
【C++】STL —— vector基本使用
|
算法 C++ 容器
STL初识 vector基础
STL初识 vector基础