Java集合 - vector

Vector

一:Vector概述

vector实现了一个可以自动增长的对象数组,类似于动态数组,能够动态的调整自身的大小,能够根据索引进行查询

vector继承了AbstractList, 实现了List接口,是一个队列,实现了相应的CRUD功能

vector实现了RandomAccess接口,可以实现对数据进行随机的访问

vector的操作是线程安全的,vector中的大部分的方法都增加了synchronized关键字修饰

在这里插入图片描述

二:源码分析

1:成员变量

public class Vector<E> extends AbstractList<E>
    	implements List<E>, RandomAccess, Cloneable, java.io.Serializable {
    
    // elementData是一个数组类型,初始化的大小是10,会随着元素的增多不断的增长。
    protected Object[] elementData;

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

   	// capacityIncrement是数组在扩容时增长的系数,如果不指定这个系数的大小时,默认为0
    // 如果capacityIncrement<=0时,那么每次扩容elementData的时候就是直接翻倍(n -> 2 * n)
    protected int capacityIncrement;

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

2:构造方法

vector中构造方法有4个

//不指定任何参数时,默认数组的大小为10
public Vector() {
	this(10);
}

//仅指定数组的大小 - 容量输入的多少就是多少
public Vector(int initialCapacity) {
    // 0是声明扩容系数为0
	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;
}

//初始化指定的集合
public Vector(Collection<? extends E> c) {
	elementData = c.toArray();
	elementCount = elementData.length;
	if (elementData.getClass() != Object[].class) {
        elementData = Arrays.copyOf(elementData, elementCount, Object[].class);
    }
}

3:增加和减少数组大小

在Vector中由于数据量是不固定大小的,当数据量超过当前的容量时,需要对数组的容量进行扩容。

每次扩容的大小是由三个参数来决定的:

  1. 扩容的目标大小minCapacity
  2. 扩容系数capacityIncrement
  3. 当前数组的容量大小

如果目标大小小于当前数组的容量,就不需要再进行扩容操作(target < cap --> nothing todo)

否则先将数组的容量按照capacityIncrement进行扩容,若扩容后的大小仍小于目标大小,那么就将容量大小改为目标大小。

每次对Vector进行结构改变的操作,例如insert、add等都会执行ensyreCapacityHelper方法对Vector的容量进行检查

🎉 而在进行扩容操作时存在数组的复制等操作,因此如果存在插入大量元素的操作时,可以提前执行一次扩容操作,减少执行ensureCapacityHelper的操作,可以提高Vector中某些方法的执行效率。

在每次执行增加元素的操作时,方法会自动调用ensureCapacityHelper的操作,使用者可以不用去担心容量是否够用,但是如果Vector的容量远大于其中存储的元素的个数时,也会存在空间的浪费,那么就可以调用trimSize方法,对Vector的中未使用到的空间进行释放。

// 数组缩容
// 减少数组占用的空间:当数组中实际存储的元素个数小于数组的容量时,可以减少数组的容量为实际存储元素大小的容量
// 存在元素的复制
public synchronized void trimToSize() {
	modCount++; // 修改次数属性 + 1
	int oldCapacity = elementData.length; // 拿到原始数组的长度
	if (elementCount < oldCapacity) { // 缩容到指定的大小
	    elementData = Arrays.copyOf(elementData, elementCount);
	}
}
// 扩展数组的容量大小为指定的minCapacity大小
public synchronized void ensureCapacity(int minCapacity) {
	modCount++;
	ensureCapacityHelper(minCapacity);
}
        
//对数组进行扩容,这个方法不是同步的,该类中的同步方法可以在内部调用这个
// 确保生产能力但是不花费额外的成本去进行同步--存在元素的复制
// 如果数组的容量小于指定的容量,先按照capacityIncrement系数进行扩容
// 如果还是小于指定的容量,则扩容到指定的容量
// 如果数组中要一次性增加大量元素时,可以先调用这个方法对数组进行扩容,避免在每次add时去扩容,减少扩容的次数
private void ensureCapacityHelper(int minCapacity) {
	int oldCapacity = elementData.length;
	if (minCapacity > oldCapacity) {
		Object[] oldData = elementData;
		int newCapacity = (capacityIncrement > 0) ?(oldCapacity + capacityIncrement) : (oldCapacity * 2);
	    	if (newCapacity < minCapacity) {
			newCapacity = minCapacity;
		}
	        elementData = Arrays.copyOf(elementData, newCapacity);
	}
}

4:vector的遍历

public static void VectorTest1() {
	Vector vector = new Vector();
	long s1 = System.currentTimeMillis();
	for(int i = 0; i< 10000000; i++) {
		vector.add(i);
	}
	//System.out.println("初始化时间:"+(System.currentTimeMillis()-s1));
	s1 = System.currentTimeMillis();
	//通过Iterator进行遍历
	Object obj = null;
	Iterator<Object> iter = vector.iterator();
	while(iter.hasNext()) {
		obj = iter.next();
	}		
	System.out.println("iterator花费时间:"+(System.currentTimeMillis()-s1));
		
	s1 = System.currentTimeMillis();
	//随机访问,通过索引进行遍历
	Object obj1 = null;
	int size = vector.size();
	for(int i = 0; i< size; i++) {
		obj1 = vector.get(i);
	}		
	System.out.println("索引遍历花费时间:"+(System.currentTimeMillis()-s1));
		
	s1 = System.currentTimeMillis();
	Object obj2 = null;
	for(Object o : vector) {
		obj2 = o;
	}
	System.out.println("for循环花费时间:"+(System.currentTimeMillis()-s1));
		
	s1 = System.currentTimeMillis();
	//通过Enumeration遍历
	Object obj3 = null;
	Enumeration enumer = vector.elements();
	while(enumer.hasMoreElements()) {
		obj3 = enumer.nextElement();
	}		
	System.out.println("Enumeration花费时间:"+(System.currentTimeMillis()-s1));
}

三:其他主要方法一览

方法说明
void setSize(int newSize)修改vector中包含的元素的个数
int capacity()返回当前vector的容量大小
int size()返回当前vector包含的元素个数
boolean isEmpty()判断vector是否为空
boolean contains(Object o)判断Vector中是否包含元素o
int indexOf(Object o)返回Vector中元素o的索引位置
int indexOf(Object o, int index)从index位置开始查询,返回元素o的位置
int lastIndexOf(Object o, int index)从index位置向前查询,最后一次
E elementAt(int index)
E get(int index)
返回index位置的元素值
E firstElement()返回第一个元素值
E lastElement()返回最后一个元素值
void setElementAt(E obj, int index)修改index位置的元素值为obj
void removeElementAt(int index)删除index位置的元素值
void insetElementAt(E obj, int index)
void add(int index, E element)
插入一个元素在index位置
void addElement(E obj)
boolean add(E e)
在数组的最后一个位置插入元素
boolean removeElement(Object obj)
boolean remove(Object obj)
删除一个元素
Object[] toArray()将vector转化为数组
T[] toArray(T[] a)将vector转化为指定的数组
E set(int index, E element)修改index位置的元素值,返回替换前的值
E remove(int index)删除index位置的值,返回删除前的值
boolean containsAll(Collection<?> c)判断vector中是否包含指定集合中的所有元素
boolean addAll(Collection<?> c)将C中的所有元素加到vector中
boolean retainAll(Collection<?> c)判断vector中是否有元素不再C中
boolean addAll(int index, Collection<?> c)在指定位置插入c中的所有元素
boolean equals(Object o)判断两个集合是否相等
List subList(int fi, int ti)截取vector,返回的类型为List,返回值时索引值为fi-ti之间的值
void removeRange(int fi, int ti)删除vector中索引值为fi到ti之间的元素

四:vector的使用

Vector为存储的对象分配的是一块连续的存储空间,他的本质上是一个动态数组,可以通过索引进行访问,因此随机访问的效率很高,但是在Vector中插入或删除一个元素时,会对数组中的元素进行复制和移动操作

当Vector中存储的数据量很大的情况下,对元素的进行复制操作时开销比较大。

而List中的元素是以链表的形式存储的,当访问一个元素的时候都需要对链表进行遍历,但是相比较Vector,List的插入和删除元素操作比较方便。

因此Vector比较适用于:对象的数量变化较少,简单对象,随机访问较频繁的情况中,而List比较适用于对象数量变化大,对象比较负责,频繁插入和删除操作的情况。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值