JAVA Vector源码解析和示例代码
第1部分 vector介绍
vector 是矢量队列,它是jdk1.0版本添加的类。继承于abstractlist,实现了list, randomaccess, cloneable这些接口。
vector 继承了abstractlist,实现了list;所以,它是一个队列,支持相关的添加、删除、修改、遍历等功能。
vector 实现了randmoaccess接口,即提供了随机访问功能。randmoaccess是java中用来被list实现,为list提供快速访问功能的。在vector中,我们即可以通过元素的序号快速获取元素对象;这就是快速随机访问。
vector 实现了cloneable接口,即实现clone()函数。它能被克隆。
和arraylist不同,vector中的操作是线程安全的;但是,vector不支持序列化,即没有实现java.io.serializable接口。
vector的继承关系
vector与collection关系如下图:
vector的构造函数
vector共有4个构造函数
// 默认构造函数
vector()
// capacity是vector的默认容量大小。当由于增加数据导致容量增加时,每次容量会增加一倍。
vector(int capacity)
// capacity是vector的默认容量大小,capacityincrement是每次vector容量增加时的增量值。
vector(int capacity, int capacityincrement)
// 创建一个包含collection的vector
vector(collection<? extends e> collection)
vector的api
synchronized boolean add(e object)
void add(int location, e object)
synchronized boolean addall(collection<? extends e> collection)
synchronized boolean addall(int location, collection<? extends e> collection)
synchronized void addelement(e object)
synchronized int capacity()
void clear()
synchronized object clone()
boolean contains(object object)
synchronized boolean containsall(collection<?> collection)
synchronized void copyinto(object[] elements)
synchronized e elementat(int location)
enumeration<e> elements()
synchronized void ensurecapacity(int minimumcapacity)
synchronized boolean equals(object object)
synchronized e firstelement()
e get(int location)
synchronized int hashcode()
synchronized int indexof(object object, int location)
int indexof(object object)
synchronized void insertelementat(e object, int location)
synchronized boolean isempty()
synchronized e lastelement()
synchronized int lastindexof(object object, int location)
synchronized int lastindexof(object object)
synchronized e remove(int location)
boolean remove(object object)
synchronized boolean removeall(collection<?> collection)
synchronized void removeallelements()
synchronized boolean removeelement(object object)
synchronized void removeelementat(int location)
synchronized boolean retainall(collection<?> collection)
synchronized e set(int location, e object)
synchronized void setelementat(e object, int location)
synchronized void setsize(int length)
synchronized int size()
synchronized list<e> sublist(int start, int end)
synchronized <t> t[] toarray(t[] contents)
synchronized object[] toarray()
synchronized string tostring()
synchronized void trimtosize()
第2部分 vector源码解析
为了更了解vector的原理,下面对vector源码代码作出分析。
package java.util;
public class vector<e>
extends abstractlist<e>
implements list<e>, randomaccess, cloneable, java.io.serializable
{
// 保存vector中数据的数组
protected object[] elementdata;
// 实际数据的数量
protected int elementcount;
// 容量增长系数
protected int capacityincrement;
// vector的序列版本号
private static final long serialversionuid = -2767605614048989439l;
// vector构造函数。默认容量是10。
public vector() {
this(10);
}
// 指定vector容量大小的构造函数
public vector(int initialcapacity) {
this(initialcapacity, 0);
}
// 指定vector"容量大小"和"增长系数"的构造函数
public vector(int initialcapacity, int capacityincrement) {
super();
if (initialcapacity < 0)
throw new illegalargumentexception("illegal capacity: "+
initialcapacity);
// 新建一个数组,数组容量是initialcapacity
this.elementdata = new object[initialcapacity];
// 设置容量增长系数
this.capacityincrement = capacityincrement;
}
// 指定集合的vector构造函数。
public vector(collection<? extends e> c) {
// 获取“集合(c)”的数组,并将其赋值给elementdata
elementdata = c.toarray();
// 设置数组长度
elementcount = elementdata.length;
// c.toarray might (incorrectly) not return object[] (see 6260652)
if (elementdata.getclass() != object[].class)
elementdata = arrays.copyof(elementdata, elementcount, object[].class);
}
// 将数组vector的全部元素都拷贝到数组anarray中
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容量”的帮助函数
private void ensurecapacityhelper(int mincapacity) {
int oldcapacity = elementdata.length;
// 当vector的容量不足以容纳当前的全部元素,增加容量大小。
// 若 容量增量系数>0(即capacityincrement>0),则将容量增大当capacityincrement
// 否则,将容量增大一倍。
if (mincapacity > oldcapacity) {
object[] olddata = elementdata;
int newcapacity = (capacityincrement > 0) ?
(oldcapacity + capacityincrement) : (oldcapacity * 2);
if (newcapacity < mincapacity) {
newcapacity = mincapacity;
}
elementdata = arrays.copyof(elementdata, newcapacity);
}
}
// 确定vector的容量。
public synchronized void ensurecapacity(int mincapacity) {
// 将vector的改变统计数+1
modcount++;
ensurecapacityhelper(mincapacity);
}
// 设置容量值为 newsize
public synchronized void setsize(int newsize) {
modcount++;
if (newsize > elementcount) {
// 若 "newsize 大于 vector容量",则调整vector的大小。
ensurecapacityhelper(newsize);
} else {
// 若 "newsize 小于/等于 vector容量",则将newsize位置开始的元素都设置为null
for (int i = newsize ; i < elementcount ; i++) {
elementdata[i] = null;
}
}
elementcount = newsize;
}
// 返回“vector的总的容量”
public synchronized int capacity() {
return elementdata.length;
}
// 返回“vector的实际大小”,即vector中元素个数
public synchronized int size() {
return elementcount;
}
// 判断vector是否为空
public synchronized boolean isempty() {
return elementcount == 0;
}
// 返回“vector中全部元素对应的enumeration”
public enumeration<e> elements() {
// 通过匿名类实现enumeration
return new enumeration<e>() {
int count = 0;
// 是否存在下一个元素
public boolean hasmoreelements() {
return count < elementcount;
}
// 获取下一个元素
public e nextelement() {
synchronized (vector.this) {
if (count < elementcount) {
return (e)elementdata[count++];
}
}
throw new nosuchelementexception("vector enumeration");
}
};
}
// 返回vector中是否包含对象(o)
public boolean contains(object o) {
return indexof(o, 0) >= 0;
}
// 从index位置开始向后查找元素(o)。
// 若找到,则返回元素的索引值;否则,返回-1
public synchronized int indexof(object o, int index) {
if (o == null) {
// 若查找元素为null,则正向找出null元素,并返回它对应的序号
for (int i = index ; i < elementcount ; i++)
if (elementdata[i]==null)
return i;
} else {
// 若查找元素不为null,则正向找出该元素,并返回它对应的序号
for (int i = index ; i < elementcount ; i++)
if (o.equals(elementdata[i]))
return i;
}
return -1;
}
// 查找并返回元素(o)在vector中的索引值
public int indexof(object o) {
return indexof(o, 0);
}
// 从后向前查找元素(o)。并返回元素的索引
public synchronized int lastindexof(object o) {
return lastindexof(o, elementcount-1);
}
// 从后向前查找元素(o)。开始位置是从前向后的第index个数;
// 若找到,则返回元素的“索引值”;否则,返回-1。
public synchronized int lastindexof(object o, int index) {
if (index >= elementcount)
throw new indexoutofboundsexception(index + " >= "+ elementcount);
if (o == null) {
// 若查找元素为null,则反向找出null元素,并返回它对应的序号
for (int i = index; i >= 0; i--)
if (elementdata[i]==null)
return i;
} else {
// 若查找元素不为null,则反向找出该元素,并返回它对应的序号
for (int i = index; i >= 0; i--)
if (o.equals(elementdata[i]))
return i;
}
return -1;
}
// 返回vector中index位置的元素。
// 若index月结,则抛出异常
public synchronized e elementat(int index) {
if (index >= elementcount) {
throw new arrayindexoutofboundsexception(index + " >= " + elementcount);
}
return (e)elementdata[index];
}
// 获取vector中的第一个元素。
// 若失败,则抛出异常!
public synchronized e firstelement() {
if (elementcount == 0) {
throw new nosuchelementexception();
}
return (e)elementdata[0];
}
// 获取vector中的最后一个元素。
// 若失败,则抛出异常!
public synchronized e lastelement() {
if (elementcount == 0) {
throw new nosuchelementexception();
}
return (e)elementdata[elementcount - 1];
}
// 设置index位置的元素值为obj
public synchronized void setelementat(e obj, int index) {
if (index >= elementcount) {
throw new arrayindexoutofboundsexception(index + " >= " +
elementcount);
}
elementdata[index] = obj;
}
// 删除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);
}
elementcount--;
elementdata[elementcount] = null; /* to let gc do its work */
}
// 在index位置处插入元素(obj)
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++;
}
// 将“元素obj”添加到vector末尾
public synchronized void addelement(e obj) {
modcount++;
ensurecapacityhelper(elementcount + 1);
elementdata[elementcount++] = obj;
}
// 在vector中查找并删除元素obj。
// 成功的话,返回true;否则,返回false。
public synchronized boolean removeelement(object obj) {
modcount++;
int i = indexof(obj);
if (i >= 0) {
removeelementat(i);
return true;
}
return false;
}
// 删除vector中的全部元素
public synchronized void removeallelements() {
modcount++;
// 将vector中的全部元素设为null
for (int i = 0; i < elementcount; i++)
elementdata[i] = null;
elementcount = 0;
}
// 克隆函数
public synchronized object clone() {
try {
vector<e> v = (vector<e>) super.clone();
// 将当前vector的全部元素拷贝到v中
v.elementdata = arrays.copyof(elementdata, elementcount);
v.modcount = 0;
return v;
} catch (clonenotsupportedexception e) {
// this shouldn't happen, since we are cloneable
throw new internalerror();
}
}
// 返回object数组
public synchronized object[] toarray() {
return arrays.copyof(elementdata, elementcount);
}
// 返回vector的模板数组。所谓模板数组,即可以将t设为任意的数据类型
public synchronized <t> t[] toarray(t[] a) {
// 若数组a的大小 < vector的元素个数;
// 则新建一个t[]数组,数组大小是“vector的元素个数”,并将“vector”全部拷贝到新数组中
if (a.length < elementcount)
return (t[]) arrays.copyof(elementdata, elementcount, a.getclass());
// 若数组a的大小 >= vector的元素个数;
// 则将vector的全部元素都拷贝到数组a中。
system.arraycopy(elementdata, 0, a, 0, elementcount);
if (a.length > elementcount)
a[elementcount] = null;
return a;
}
// 获取index位置的元素
public synchronized e get(int index) {
if (index >= elementcount)
throw new arrayindexoutofboundsexception(index);
return (e)elementdata[index];
}
// 设置index位置的值为element。并返回index位置的原始值
public synchronized e set(int index, e element) {
if (index >= elementcount)
throw new arrayindexoutofboundsexception(index);
object oldvalue = elementdata[index];
elementdata[index] = element;
return (e)oldvalue;
}
// 将“元素e”添加到vector最后。
public synchronized boolean add(e e) {
modcount++;
ensurecapacityhelper(elementcount + 1);
elementdata[elementcount++] = e;
return true;
}
// 删除vector中的元素o
public boolean remove(object o) {
return removeelement(o);
}
// 在index位置添加元素element
public void add(int index, e element) {
insertelementat(element, index);
}
// 删除index位置的元素,并返回index位置的原始值
public synchronized e remove(int index) {
modcount++;
if (index >= elementcount)
throw new arrayindexoutofboundsexception(index);
object oldvalue = elementdata[index];
int nummoved = elementcount - index - 1;
if (nummoved > 0)
system.arraycopy(elementdata, index+1, elementdata, index,
nummoved);
elementdata[--elementcount] = null; // let gc do its work
return (e)oldvalue;
}
// 清空vector
public void clear() {
removeallelements();
}
// 返回vector是否包含集合c
public synchronized boolean containsall(collection<?> c) {
return super.containsall(c);
}
// 将集合c添加到vector中
public synchronized boolean addall(collection<? extends e> c) {
modcount++;
object[] a = c.toarray();
int numnew = a.length;
ensurecapacityhelper(elementcount + numnew);
// 将集合c的全部元素拷贝到数组elementdata中
system.arraycopy(a, 0, elementdata, elementcount, numnew);
elementcount += numnew;
return numnew != 0;
}
// 删除集合c的全部元素
public synchronized boolean removeall(collection<?> c) {
return super.removeall(c);
}
// 删除“非集合c中的元素”
public synchronized boolean retainall(collection<?> c) {
return super.retainall(c);
}
// 从index位置开始,将集合c添加到vector中
public synchronized boolean addall(int index, collection<? extends e> c) {
modcount++;
if (index < 0 || index > elementcount)
throw new arrayindexoutofboundsexception(index);
object[] a = c.toarray();
int numnew = a.length;
ensurecapacityhelper(elementcount + numnew);
int nummoved = elementcount - index;
if (nummoved > 0)
system.arraycopy(elementdata, index, elementdata, index + numnew, nummoved);
system.arraycopy(a, 0, elementdata, index, numnew);
elementcount += numnew;
return numnew != 0;
}
// 返回两个对象是否相等
public synchronized boolean equals(object o) {
return super.equals(o);
}
// 计算哈希值
public synchronized int hashcode() {
return super.hashcode();
}
// 调用父类的tostring()
public synchronized string tostring() {
return super.tostring();
}
// 获取vector中fromindex(包括)到toindex(不包括)的子集
public synchronized list<e> sublist(int fromindex, int toindex) {
return collections.synchronizedlist(super.sublist(fromindex, toindex), this);
}
// 删除vector中fromindex到toindex的元素
protected synchronized void removerange(int fromindex, int toindex) {
modcount++;
int nummoved = elementcount - toindex;
system.arraycopy(elementdata, toindex, elementdata, fromindex,
nummoved);
// let gc do its work
int newelementcount = elementcount - (toindex-fromindex);
while (elementcount != newelementcount)
elementdata[--elementcount] = null;
}
// java.io.serializable的写入函数
private synchronized void writeobject(java.io.objectoutputstream s)
throws java.io.ioexception {
s.defaultwriteobject();
}
}
总结:
(01) vector实际上是通过一个数组去保存数据的。当我们构造vecotr时;若使用默认构造函数,则vector的默认容量大小是10。
(02) 当vector容量不足以容纳全部元素时,vector的容量会增加。若容量增加系数 >0,则将容量的值增加“容量增加系数”;否则,将容量大小增加一倍。
(03) vector的克隆函数,即是将全部元素克隆到一个数组中。
第3部分 vector遍历方式
vector支持4种遍历方式。建议使用下面的第二种去遍历vector,因为效率问题。
(01) 第一种,通过迭代器遍历。即通过iterator去遍历。
integer value = null;
int size = vec.size();
for (int i=0; i<size; i++) {
value = (integer)vec.get(i);
}
(02) 第二种,随机访问,通过索引值去遍历。
由于vector实现了randomaccess接口,它支持通过索引值去随机访问元素。
integer value = null;
int size = vec.size();
for (int i=0; i<size; i++) {
value = (integer)vec.get(i);
}
(03) 第三种,另一种for循环。如下:
integer value = null;
for (integer integ:vec) {
value = integ;
}
(04) 第四种,enumeration遍历。如下:
integer value = null;
enumeration enu = vec.elements();
while (enu.hasmoreelements()) {
value = (integer)enu.nextelement();
}
测试这些遍历方式效率的代码如下:
import java.util.*;
/*
* @desc vector遍历方式和效率的测试程序。
*
* @author skywang
*/
public class vectorrandomaccesstest {
public static void main(string[] args) {
vector vec= new vector();
for (int i=0; i<100000; i++)
vec.add(i);
iteratorthroughrandomaccess(vec) ;
iteratorthroughiterator(vec) ;
iteratorthroughfor2(vec) ;
iteratorthroughenumeration(vec) ;
}
private static void israndomaccesssupported(list list) {
if (list instanceof randomaccess) {
system.out.println("randomaccess implemented!");
} else {
system.out.println("randomaccess not implemented!");
}
}
public static void iteratorthroughrandomaccess(list list) {
long starttime;
long endtime;
starttime = system.currenttimemillis();
for (int i=0; i<list.size(); i++) {
list.get(i);
}
endtime = system.currenttimemillis();
long interval = endtime - starttime;
system.out.println("iteratorthroughrandomaccess:" + interval+" ms");
}
public static void iteratorthroughiterator(list list) {
long starttime;
long endtime;
starttime = system.currenttimemillis();
for(iterator iter = list.iterator(); iter.hasnext(); ) {
iter.next();
}
endtime = system.currenttimemillis();
long interval = endtime - starttime;
system.out.println("iteratorthroughiterator:" + interval+" ms");
}
public static void iteratorthroughfor2(list list) {
long starttime;
long endtime;
starttime = system.currenttimemillis();
for(object obj:list)
endtime = system.currenttimemillis();
long interval = endtime - starttime;
system.out.println("iteratorthroughfor2:" + interval+" ms");
}
public static void iteratorthroughenumeration(vector vec) {
long starttime;
long endtime;
starttime = system.currenttimemillis();
for(enumeration enu = vec.elements(); enu.hasmoreelements(); ) {
enu.nextelement();
}
endtime = system.currenttimemillis();
long interval = endtime - starttime;
system.out.println("iteratorthroughenumeration:" + interval+" ms");
}
}
运行结果:
iteratorthroughrandomaccess:6 ms
iteratorthroughiterator:9 ms
iteratorthroughfor2:8 ms
iteratorthroughenumeration:7 ms
总结:遍历vector,使用索引的随机访问方式最快,使用迭代器最慢。
第4部分 vector示例
下面通过示例学习如何使用vector
import java.util.vector;
import java.util.list;
import java.util.iterator;
import java.util.enumeration;
/**
* @desc vector测试函数:遍历vector和常用api
*
* @author skywang
*/
public class vectortest {
public static void main(string[] args) {
// 新建vector
vector vec = new vector();
// 添加元素
vec.add("1");
vec.add("2");
vec.add("3");
vec.add("4");
vec.add("5");
// 设置第一个元素为100
vec.set(0, "100");
// 将“500”插入到第3个位置
vec.add(2, "300");
system.out.println("vec:"+vec);
// (顺序查找)获取100的索引
system.out.println("vec.indexof(100):"+vec.indexof("100"));
// (倒序查找)获取100的索引
system.out.println("vec.lastindexof(100):"+vec.lastindexof("100"));
// 获取第一个元素
system.out.println("vec.firstelement():"+vec.firstelement());
// 获取第3个元素
system.out.println("vec.elementat(2):"+vec.elementat(2));
// 获取最后一个元素
system.out.println("vec.lastelement():"+vec.lastelement());
// 获取vector的大小
system.out.println("size:"+vec.size());
// 获取vector的总的容量
system.out.println("capacity:"+vec.capacity());
// 获取vector的“第2”到“第4”个元素
system.out.println("vec 2 to 4:"+vec.sublist(1, 4));
// 通过enumeration遍历vector
enumeration enu = vec.elements();
while(enu.hasmoreelements())
system.out.println("nextelement():"+enu.nextelement());
vector retainvec = new vector();
retainvec.add("100");
retainvec.add("300");
// 获取“vec”中包含在“retainvec中的元素”的集合
system.out.println("vec.retain():"+vec.retainall(retainvec));
system.out.println("vec:"+vec);
// 获取vec对应的string数组
string[] arr = (string[]) vec.toarray(new string[0]);
for (string str:arr)
system.out.println("str:"+str);
// 清空vector。clear()和removeallelements()一样!
vec.clear();
// vec.removeallelements();
// 判断vector是否为空
system.out.println("vec.isempty():"+vec.isempty());
}
}
上一篇: Java多线程饥饿与公平介绍及代码示例