一.介绍
Vector 本质是一个数组,当然他具有数组的通过下标访问等特性,同时这玩意儿继承了 AbstractList 。当然他具有了集合的通用功能,同时他实现了 List,RandomAccess,Cloneable ,Sertializable 接口。
这里大概提一下RandomAccess 和 Cloneable 。
1.1 RandomAccess 可以让其拥有随机访问的能力,可以用迭代器进行迭代,某些情况 下 会有更好性能。没有就无法使用Iterator迭代器。
1.2 Cloneable 会提供Object 的clone 功能,没有就无法clone。
关于这里的研究我们以后再谈,还是先来说Vector 。
二.代码分析
2.1 Vector 的属性 :
protected Object[] elementData; 这是用来存放元素的。
protected int elementCount; 这是记录这个对象存放了好多个元素
protected int capacityIncrement; 这是增长因子,就是你数组放不下了,增加容量。
2.2 构造方法:
public Vector() {
this(10);
}
public Vector(int initialCapacity, int capacityIncrement) {
this.elementData = new Object[initialCapacity];
this.capacityIncrement = capacityIncrement;
}
public Vector(int initialCapacity) {
this(initialCapacity, 0);
}
这里我取了主要部分,从构造不难看出,我们默认 new Vector(),实际上是通过public Vector(int initialCapacity, int capacityIncrement) 方法,创建了长度为10 ,增长因子为0 的Object 数组。这里如果大概知道数组长度,请指定长度,必然复制数组带来的开销。
public Vector(Collection<? extends E> c) {
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对象里面。
3.3 方法介绍:这里只介绍几个主要的,其余可以查询API
public synchronized boolean add(E e) {
modCount++;
ensureCapacityHelper(elementCount + 1);
elementData[elementCount++] = e;
return true;
}
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);
}
}
方法:add(E e):
就是添加一个元素,这里通过ensureCapacityHelper 方法进行判断添加的个数,从ensureCapacityHelper(elementCount + 1);知道,默认是添加一个,这里添加的个数如果超出了原来数组的长度,就用Arrays.copyOf 进行扩容,底层用的System.arraycopy 方法,默认元素加载末尾。关于 modCount 字段是集合用来快速判断迭代过程中失败的标志,也就是说 如果集合在地带过程中,进行了删除等操作 就会报错。
同理:
方法:add(int index,E element) 向指定位置添加元素,实际上访问的是:
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++;
}
但是你发现 最终都是 调用 ensureCapacityHelper 等方法。
还有: public synchronized void addElement(E obj) 方法,和add方法相比,只是返回值不一样,一个是boolean,一个是 void 内部完全一样。
方法: public boolean contains(Object o) 判断元素是否存在,实际访问的是:
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 Enumeration<E> elements()
这里是创建了一个枚举类型,里面实现还是通过元素是否存在,通过下标遍历数组
public Enumeration<E> elements() {
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");
}
};
}
当然还有其他方法,就不多做介绍了,就是数组元素的操作而已。
小结:
1.Vector 本质是一个数组,其实所有集合都是数组,从JAVA 来说搞成了对象,符合我 们的OO,可以参考学习。
2.Vector 源码看出很多方法都是synchronized 的,线程安全,但是效率就不得不 损耗点了,多线程开发可以使用。
允许的情况,我们可以参考这种模式,设计自己的vector 类,或者其他类,以便于更适应我们的项目。不要把这些看得很圣神,其实都是你和JDK开发人员,差距没那么大,相信自己。