栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Vector源码阅读分析

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Vector源码阅读分析

Vector源码阅读分析 1.1 Vertor介绍

Vector 是矢量队列,它是JDK1.0版本添加的类。继承于AbstractList,实现了List, RandomAccess, Cloneable这些接口。
Vector 继承了AbstractList,实现了List;所以,它是一个队列,支持相关的添加、删除、修改、遍历等功能。
Vector 实现了RandmoAccess接口,即提供了随机访问功能。RandmoAccess是java中用来被List实现,为List提供快速访问功能的。在Vector中,我们即可以通过元素的序号快速获取元素对象;这就是快速随机访问。
Vector 实现了Cloneable接口,即实现clone()函数。它能被克隆。

Vector 实现Serializable接口,这意味着linkedList支持序列化,能通过序列化去传输。

和ArrayList不同,Vector中的操作是线程安全的。

1.2 Vertor源码
public class Vector
    extends AbstractList
    implements List, RandomAccess, Cloneable, java.io.Serializable
{
    
    // 存储元素的数组
    protected Object[] elementData;

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

    
    
 	// vector需要自动扩容时增加的容量。
	//当vector的实际容量elementCount将要大于它的最大容量时,vector自动增加的容量。
 	// 如果capacityIncrement小于或等于0,vector的容量需要增长时将会成倍增长。
    protected int capacityIncrement;
1.2.2 Vector构造方法 (1). Vector()

无参构造

构造一个指定容量为10、自增容量为0的空vector。

public Vector() {
    // 调用Vector(int initialCapacity)方法
    this(10);
}
(2). Vector(Collection c)

传入一个集合构造Vector

public Vector(Collection c) {
    // 集合转换成数组
    Object[] a = c.toArray();
    // 获取数组长度
    elementCount = a.length;
    // 判断C的类型是否为ArrayList类型,如果是的话,直接将a赋值给数组elementData
    if (c.getClass() == ArrayList.class) {
        elementData = a;
    } else {
        // 拷贝数组a到一个长度为elementCount的数组
        elementData = Arrays.copyOf(a, elementCount, Object[].class);
    }
}
(3). Vector(int initialCapacity)

构造一个指定容量为initialCapacity、自增容量为0的空vector。

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

构造一个指定容量为initialCapacity、自增容量为capacityIncrement的vector。

public Vector(int initialCapacity, int capacityIncrement) {
    super();
    // 检验自增容量是否小于0,小于0直接抛出异常
    if (initialCapacity < 0)
        throw new IllegalArgumentException("Illegal Capacity: "+
                                           initialCapacity);
    // 创建一个长度为initialCapacity的数组
    this.elementData = new Object[initialCapacity];
    // 设置自增容量
    this.capacityIncrement = capacityIncrement;
}
1.2.3 Vector增加元素 (1). add(E e)

在数组末尾添加一个元素

添加synchronized修饰方法,代表是线程安全的

public synchronized boolean add(E e) {
    // 结构性修改次数自增+1
    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;
    // 扩容
    // 如果自增容量大于0,则扩容为oldCapacity+capacityIncrement
    // 否则对数组容量进行翻倍扩容
    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) {
    // minCapacity小于0 抛出异常
    if (minCapacity < 0) // overflow
        throw new OutOfMemoryError();
    // 如果minCapacity大于MAX_ARRAY_SIZE,则复制为Integer的最大值,否则为MAX_ARRAY_SIZE
    return (minCapacity > MAX_ARRAY_SIZE) ?
        Integer.MAX_VALUE :
    MAX_ARRAY_SIZE;
}
(2). add(int index, E element)

在指定索引位置添加一个元素

insertElementAt添加了synchronized修饰符标记

public void add(int index, E element) {
    // 调用insertElementAt插入数据
    insertElementAt(element, index);
}


public synchronized void insertElementAt(E obj, int index) {
    // 结构性修改次数自增+1
    modCount++;
    // 判断插入的索引位置是否越界
    if (index > elementCount) {
        throw new ArrayIndexOutOfBoundsException(index
                                                 + " > " + elementCount);
    }
    // 判断数组是否需要扩容
    ensureCapacityHelper(elementCount + 1);
    // 将inex及其之后的元素往后挪一位,则index位置处就空出来了
    System.arraycopy(elementData, index, elementData, index + 1, elementCount - index);、
    // 在index索引位置处放入需要插入的元素
    elementData[index] = obj;
    // 元素长度自增+1
    elementCount++;
}
(3). addAll(Collection c)

添加一个集合

public synchronized boolean addAll(Collection c) {
    modCount++;
    Object[] a = c.toArray();
    int numNew = a.length;
    // 判断是否需要扩容
    ensureCapacityHelper(elementCount + numNew);
    // 将集合插入在数组末尾的位置
    System.arraycopy(a, 0, elementData, elementCount, numNew);
    // 修改数组元素的个数
    elementCount += numNew;
    // 返回是否添加成功,当传入的集合长度为0 时返回false代表插入失败
    return numNew != 0;
}
(4). addAll(int index, Collection c)

在指定的索引位置插入一个集合

public synchronized boolean addAll(int index, Collection c) {
    // 结构性修改次数自增+1
    modCount++;
    // 判断索引是否越界
    if (index < 0 || index > elementCount)
        throw new ArrayIndexOutOfBoundsException(index);

    Object[] a = c.toArray();
    int numNew = a.length;
    // 判断是否需要进行扩容
    ensureCapacityHelper(elementCount + numNew);
	// 如果index不是最后一位,则将index之后的元素往后挪numNew个位置,将从numMoved的位置空出放入传入的元素
    int numMoved = elementCount - index;
    if (numMoved > 0)
        System.arraycopy(elementData, index, elementData, index + numNew,
                         numMoved);
	// 将c中元素全部拷贝到数组
    System.arraycopy(a, 0, elementData, index, numNew);
    // 修改数组元素的个数
    elementCount += numNew;
    // 如果c不为空就返回true,否则返回false
    return numNew != 0;
}
(5). addElement(E obj)

添加一个元素

public synchronized void addElement(E obj) {
    // 结构性修改次数+1
    modCount++;
    // 判断是否需要扩容
    ensureCapacityHelper(elementCount + 1);
   	// 在数组末尾出插入元素
    elementData[elementCount++] = obj;
}
1.2.4 Vector删除元素 (1). clear()

清空元素

public void clear() {
    // 删除所有元素
    removeAllElements();
}

public synchronized void removeAllElements() {
    modCount++;
    // Let gc do its work
    // 遍历数组 将数组的值都设置为null,协助GC进行垃圾回收
    for (int i = 0; i < elementCount; i++)
        elementData[i] = null;
	// 将数组的元素个数重置为0 
    elementCount = 0;
}
(2). remove(int index)

删除指定索引位置元素

public synchronized E remove(int index) {
    // 记录结构性改变的次数
    modCount++;
    // 判断索引是否越界
    if (index >= elementCount)
        throw new ArrayIndexOutOfBoundsException(index);
    E oldValue = elementData(index);
	// 如果index不是最后一位,则将index之后的元素往前挪一位
    int numMoved = elementCount - index - 1;
    if (numMoved > 0)
        System.arraycopy(elementData, index+1, elementData, index,
                         numMoved);
    // 将最后一个元素删除,帮助GC  
    elementData[--elementCount] = null; // Let gc do its work
	// 返回删除的旧元素
    return oldValue;
}
(3). remove(Object o)

删除一个指定的元素

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

public synchronized boolean removeElement(Object obj) {
    // 结构性修改次数+1
    modCount++;
    // 查找元素在数组中的索引位置
    int i = indexOf(obj);
    // 如果在数组中存在,则做进一步的删除操作
    if (i >= 0) {
        removeElementAt(i);
        return true;
    }
    return false;
}

public synchronized void removeElementAt(int index) {
    // 结构性修改次数自增+1
    modCount++;
    // 判断索引是否越界
    if (index >= elementCount) {
        throw new ArrayIndexOutOfBoundsException(index + " >= " +
                                                 elementCount);
    }`   
    else if (index < 0) {
        throw new ArrayIndexOutOfBoundsException(index);
    }
    // 如果index不是最后一位,则将index之后的元素往前挪一位
    int j = elementCount - index - 1;
    if (j > 0) {
        System.arraycopy(elementData, index + 1, elementData, index, j);
    }
  	// 元素个数自减1
    elementCount--;
    // 将最后一个元素删除,帮助GC  
    elementData[elementCount] = null; 
}
(4). removeAll(Collection c)

删除指定的元素

public synchronized boolean removeAll(Collection c) {
    // 调用父类AbstractCollection的removeAll方法
    return super.removeAll(c);
}

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;
}
(5).removeAllElements()

删除所有元素

public synchronized void removeAllElements() {
    modCount++;
    // Let gc do its work
    // 遍历数组 将数组的值都设置为null,协助GC进行垃圾回收
    for (int i = 0; i < elementCount; i++)
        elementData[i] = null;
	// 将数组的元素个数重置为0 
    elementCount = 0;
}

1.2.5 Vector修改元素 (1). set(int index, E element)

根据索引修改元素

public synchronized E set(int index, E element) {
    // 判断索引是否越界
    if (index >= elementCount)
        throw new ArrayIndexOutOfBoundsException(index);
	// 获取要被修改的旧元素
    E oldValue = elementData(index);
    // 将指定索引位置的元素进行替换
    elementData[index] = element;
    // 返回被修改的元素
    return oldValue;
}
// 根据索引获取数据
E elementData(int index) {
    return (E) elementData[index];
}
(2). setElementAt(E obj, int index)

根据索引修改元素

public synchronized void setElementAt(E obj, int index) {
    // 判断索引是否越界
    if (index >= elementCount) {
        throw new ArrayIndexOutOfBoundsException(index + " >= " +
                                                 elementCount);
    }
    // 根据索引获取数据
    elementData[index] = obj;
}
(3). setSize(int newSize)

修改数组大小

public synchronized void setSize(int newSize) {
    // 结构性修改次数自增+1
    modCount++;
    // 传入的新大小大于数组现在的大小,对数组进行扩容
    if (newSize > elementCount) {
        ensureCapacityHelper(newSize);
    } else {
        // 否则,对于现在数组超过新大小的部分进行清空操作
        for (int i = newSize ; i < elementCount ; i++) {
            elementData[i] = null;
        }
    }
    // 修改数组元素个数
    elementCount = newSize;
}
1.2.6 Vector查找元素 (1). E get(int index)
public synchronized E get(int index) {
    // 判断索引是否越界
    if (index >= elementCount)
        throw new ArrayIndexOutOfBoundsException(index);
	// 根据索引返回元素
    return elementData(index);
}
(2). E firstElement()

获取第一个元素

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

获取最后一个元素

public synchronized E lastElement() {
    if (elementCount == 0) {
        throw new NoSuchElementException();
    }
    return elementData(elementCount - 1);
}
(4). int lastIndexOf(Object o)

查找元素最后出现的位置

public synchronized int lastIndexOf(Object o) {
    // 从元素末尾开始进行查找
    return lastIndexOf(o, elementCount-1);
}
(5). int 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;
}
1.3 Vector总结

1、Vector创建时默认大小为10
2、Vector每次扩容但都是以当前数组的2倍扩容,当指定了capacityIncrement后,每次扩容仅在原有基础上增加capacityIncrement个空间(如果指定的空间大小不满足数组增加元素的需求,则依旧是以当前数组的两倍进行扩容)。
3、Vector和ArrayList的add、get、size方法时间复杂度都为 O(1),remove方法的时间复杂度为O(n)
4、ArrayList是线程不安全的,Vector是线程安全的。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/340113.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号