Vector源码分析和实例应用

时间:2022-03-22 04:21:35

1、Vector介绍

  • Vector 是矢量队列,它是JDK1.0版本添加的类。继承于AbstractList,实现了List, RandomAccess, Cloneable这些接口。
  • Vector 继承了AbstractList,实现了List;所以,它是一个队列,支持相关的添加、删除、修改、遍历等功能
  • Vector 实现了RandmoAccess接口,即提供了随机访问功能。RandmoAccess接口被List实现以便于为List提供快速访问功能。在Vector中,我们即可以通过元素的下角标快速获取元素对象,这就是快速随机访问。
  • Vector 实现了Cloneable接口,即实现clone()函数。它能被克隆。
  • Vector 实现了java.io.Serializable接口,说明vector支持序列化
  • 和ArrayList不同,Vector中的操作是线程安全的

2、Vector数据结构

1 java.lang.Object
2    ↳     java.util.AbstractCollection<E>
3          ↳     java.util.AbstractList<E>
4                ↳     java.util.Vector<E>
5 
6 public class Vector<E>
7     extends AbstractList<E>
8     implements List<E>, RandomAccess, Cloneable, java.io.Serializable {}

 

Vector源码分析和实例应用

 

 

Vector的数据结构和ArrayList差不多,它包含了3个成员变量:elementData , elementCount, capacityIncrement。

(01) elementData 是"Object[]类型的数组",它保存了添加到Vector中的元素。elementData是个动态数组,如果初始化Vector时,没指定动态数组的>大小,则使用默认大小10。随着Vector中元素的增加,Vector的容量也会动态增长,capacityIncrement是与容量增长相关的增长系数,具体的增长方式,请参考源码分析中的ensureCapacity()函数。

(02) elementCount 是动态数组的实际大小。

(03) capacityIncrement 是动态数组的增长系数。如果在创建Vector时,指定了capacityIncrement的大小;则,每次当Vector中动态数组容量增加时>,增加的大小都是capacityIncrement。

3、Vector源码分析

Vector源码分析和实例应用Vector源码分析和实例应用
  1 package java.util;
  2 
  3 public class Vector<E>
  4     extends AbstractList<E>
  5     implements List<E>, RandomAccess, Cloneable, java.io.Serializable
  6 {
  7    
  8     // 保存Vector中数据的数组
  9     protected Object[] elementData;
 10 
 11     // 实际数据的数量
 12     protected int elementCount;
 13 
 14     // 容量增长系数
 15     protected int capacityIncrement;
 16 
 17     // Vector的序列版本号
 18     private static final long serialVersionUID = -2767605614048989439L;
 19 
 20     // Vector构造函数。默认容量是10。
 21     public Vector() {
 22         this(10);
 23     }
 24 
 25     // 指定Vector容量大小的构造函数
 26     public Vector(int initialCapacity) {
 27         this(initialCapacity, 0);
 28     }
 29 
 30     // 指定Vector"容量大小"和"增长系数"的构造函数
 31     public Vector(int initialCapacity, int capacityIncrement) {
 32         super();
 33         if (initialCapacity < 0)
 34             throw new IllegalArgumentException("Illegal Capacity: "+
 35                                                initialCapacity);
 36         // 新建一个数组,数组容量是initialCapacity
 37         this.elementData = new Object[initialCapacity];
 38         // 设置容量增长系数
 39         this.capacityIncrement = capacityIncrement;
 40     }
 41 
 42     // 指定集合的Vector构造函数。
 43     public Vector(Collection<? extends E> c) {
 44         // 获取“集合(c)”的数组,并将其赋值给elementData
 45         elementData = c.toArray();
 46         // 设置数组长度
 47         elementCount = elementData.length;
 48         // c.toArray might (incorrectly) not return Object[] (see 6260652)
 49         if (elementData.getClass() != Object[].class)
 50             elementData = Arrays.copyOf(elementData, elementCount, Object[].class);
 51     }
 52 
 53     // 将数组Vector的全部元素都拷贝到数组anArray中
 54     public synchronized void copyInto(Object[] anArray) {
 55         System.arraycopy(elementData, 0, anArray, 0, elementCount);
 56     }
 57 
 58     // 将当前容量值设为实际元素个数
 59     public synchronized void trimToSize() {
 60         modCount++;
 61         int oldCapacity = elementData.length;
 62         if (elementCount < oldCapacity) {
 63             elementData = Arrays.copyOf(elementData, elementCount);
 64         }
 65     }
 66 
 67     // 确认“Vector容量”的帮助函数
 68     private void ensureCapacityHelper(int minCapacity) {
 69         int oldCapacity = elementData.length;
 70         // 当Vector的容量不足以容纳当前的全部元素,增加容量大小。
 71         // 若 容量增量系数>0(即capacityIncrement>0),则将容量增大当capacityIncrement
 72         // 否则,将容量增大一倍。
 73         if (minCapacity > oldCapacity) {
 74             Object[] oldData = elementData;
 75             int newCapacity = (capacityIncrement > 0) ?
 76                 (oldCapacity + capacityIncrement) : (oldCapacity * 2);
 77             if (newCapacity < minCapacity) {
 78                 newCapacity = minCapacity;
 79             }
 80             elementData = Arrays.copyOf(elementData, newCapacity);
 81         }
 82     }
 83 
 84     // 确定Vector的容量。
 85     public synchronized void ensureCapacity(int minCapacity) {
 86         // 将Vector的改变统计数+1
 87         modCount++;
 88         ensureCapacityHelper(minCapacity);
 89     }
 90 
 91     // 设置容量值为 newSize
 92     public synchronized void setSize(int newSize) {
 93         modCount++;
 94         if (newSize > elementCount) {
 95             // 若 "newSize 大于 Vector容量",则调整Vector的大小。
 96             ensureCapacityHelper(newSize);
 97         } else {
 98             // 若 "newSize 小于/等于 Vector容量",则将newSize位置开始往后的元素都设置为null
 99             for (int i = newSize ; i < elementCount ; i++) {
100                 elementData[i] = null;
101             }
102         }
103         //最后一定是要保证当前的数组容量就是等于设置的容量大小
104         elementCount = newSize;
105     }
106 
107     // 返回“Vector的总的容量”,这里的总的容量不定是数组中世纪元素的个数
108     public synchronized int capacity() {
109         return elementData.length;
110     }
111 
112     // 返回“Vector的实际大小”,即Vector中实际元素个数
113     public synchronized int size() {
114         return elementCount;
115     }
116 
117     // 判断Vector是否为空
118     public synchronized boolean isEmpty() {
119         return elementCount == 0;
120     }
121 
122     // 返回“Vector中全部元素对应的Enumeration”
123     public Enumeration<E> elements() {
124         // 通过匿名类方式实现Enumeration类
125         return new Enumeration<E>() {
126             int count = 0;
127 
128             // 是否存在下一个元素
129             public boolean hasMoreElements() {
130                 return count < elementCount;
131             }
132 
133             // 获取下一个元素
134             public E nextElement() {
135                 synchronized (Vector.this) {
136                     if (count < elementCount) {
137                         return (E)elementData[count++];
138                     }
139                 }
140                 throw new NoSuchElementException("Vector Enumeration");
141             }
142         };
143     }
144 
145     // 返回Vector中是否包含对象(o)
146     public boolean contains(Object o) {
147         return indexOf(o, 0) >= 0;
148     }
149 
150 
151     // 从index位置开始向后查找元素(o)。
152     // 若找到,则返回元素的索引值;否则,返回-1
153     public synchronized int indexOf(Object o, int index) {
154         if (o == null) {
155             // 若查找元素为null,则正向找出null元素,并返回它对应的序号
156             for (int i = index ; i < elementCount ; i++)
157             if (elementData[i]==null)
158                 return i;
159         } else {
160             // 若查找元素不为null,则正向找出该元素,并返回它对应的序号
161             for (int i = index ; i < elementCount ; i++)
162             if (o.equals(elementData[i]))
163                 return i;
164         }
165         return -1;
166     }
167 
168     // 查找并返回元素(o)在Vector中的索引值,这里相当于是从第一个位置开始查找,调用的还是indexOf(Object o, int index) 函数
169     public int indexOf(Object o) {
170         return indexOf(o, 0);
171     }
172 
173     // 从后向前查找元素(o)。并返回元素的索引
174     public synchronized int lastIndexOf(Object o) {
175         return lastIndexOf(o, elementCount-1);
176     }
177 
178     // 从后向前查找元素(o)。开始位置是从前向后的第index个数;
179     // 若找到,则返回元素的“索引值”;否则,返回-1。
180     public synchronized int lastIndexOf(Object o, int index) {
181         //首先判断输入的索引值时候合法
182         if (index >= elementCount)
183             throw new IndexOutOfBoundsException(index + " >= "+ elementCount);
184         //然后分对象是否为空两种情况
185         if (o == null) {
186             // 若查找元素为null,则反向找出null元素,并返回它对应的序号
187             for (int i = index; i >= 0; i--)
188             if (elementData[i]==null)
189                 return i;
190         } else {
191             // 若查找元素不为null,则反向找出该元素,并返回它对应的序号
192             for (int i = index; i >= 0; i--)
193             if (o.equals(elementData[i]))
194                 return i;
195         }
196         return -1;
197     }
198 
199     // 返回Vector中index位置的元素。
200     // 若index输入非法,则抛出异常
201     public synchronized E elementAt(int index) {
202         if (index >= elementCount) {
203             throw new ArrayIndexOutOfBoundsException(index + " >= " + elementCount);
204         }
205 
206         return (E)elementData[index];
207     }
208 
209     // 获取Vector中的第一个元素。
210     // 若数组为空,则抛出异常!
211     public synchronized E firstElement() {
212         if (elementCount == 0) {
213             throw new NoSuchElementException();
214         }
215         return (E)elementData[0];
216     }
217 
218     // 获取Vector中的最后一个元素。
219     // 若数组为空,则抛出异常!
220     public synchronized E lastElement() {
221         if (elementCount == 0) {
222             throw new NoSuchElementException();
223         }
224         return (E)elementData[elementCount - 1];
225     }
226 
227     // 设置index位置的元素值为obj
228     public synchronized void setElementAt(E obj, int index) {
229         if (index >= elementCount) {
230             throw new ArrayIndexOutOfBoundsException(index + " >= " +
231                                  elementCount);
232         }
233         elementData[index] = obj;
234     }
235 
236     // 删除index位置的元素,这个操作比较麻烦一点
237     public synchronized void removeElementAt(int index) {
238         modCount++;
239         if (index >= elementCount) {
240             throw new ArrayIndexOutOfBoundsException(index + " >= " +
241                                  elementCount);
242         } else if (index < 0) {
243             throw new ArrayIndexOutOfBoundsException(index);
244         }
245 
246         int j = elementCount - index - 1;
247         if (j > 0) {
248             System.arraycopy(elementData, index + 1, elementData, index, j);
249         }
250         elementCount--;
251         elementData[elementCount] = null; /* to let gc do its work */
252     }
253 
254     // 在index位置处插入元素(obj)
255     public synchronized void insertElementAt(E obj, int index) {
256         modCount++;
257         if (index > elementCount) {
258             throw new ArrayIndexOutOfBoundsException(index
259                                  + " > " + elementCount);
260         }
261         //确保数组长度能够装下这个元素
262         ensureCapacityHelper(elementCount + 1);
263         //调用 System.arraycopy()函数把当前要插入位置空出来,该索引值后边的元素全部向后移动一个位置
264         System.arraycopy(elementData, index, elementData, index + 1, elementCount - index);
265         elementData[index] = obj;
266         elementCount++;
267     }
268 
269     // 将“元素obj”添加到Vector末尾
270     public synchronized void addElement(E obj) {
271         modCount++;
272         ensureCapacityHelper(elementCount + 1);
273         elementData[elementCount++] = obj;
274     }
275 
276     // 在Vector中查找并删除元素obj。
277     // 成功的话,返回true;否则,返回false。
278     public synchronized boolean removeElement(Object obj) {
279         modCount++;
280         int i = indexOf(obj);
281         if (i >= 0) {
282             removeElementAt(i);
283             return true;
284         }
285         return false;
286     }
287 
288     // 删除Vector中的全部元素
289     public synchronized void removeAllElements() {
290         modCount++;
291         // 将Vector中的全部元素设为null
292         for (int i = 0; i < elementCount; i++)
293             elementData[i] = null;
294         elementCount = 0;
295     }
296 
297     // 克隆函数
298     public synchronized Object clone() {
299         try {
300             Vector<E> v = (Vector<E>) super.clone();
301             // 将当前Vector的全部元素拷贝到v中
302             v.elementData = Arrays.copyOf(elementData, elementCount);
303             v.modCount = 0;
304             return v;
305         } catch (CloneNotSupportedException e) {
306             // this shouldn't happen, since we are Cloneable
307             throw new InternalError();
308         }
309     }
310 
311     // 返回Object数组
312     public synchronized Object[] toArray() {
313         return Arrays.copyOf(elementData, elementCount);
314     }
315 
316     // 返回Vector的模板数组。所谓模板数组,即可以将T设为任意的数据类型
317     public synchronized <T> T[] toArray(T[] a) {
318         // 若数组a的大小 < Vector的元素个数;
319         // 则新建一个T[]数组,数组大小是“Vector的元素个数”,并将“Vector”全部拷贝到新数组中
320         if (a.length < elementCount)
321             return (T[]) Arrays.copyOf(elementData, elementCount, a.getClass());
322 
323         // 若数组a的大小 >= Vector的元素个数;
324         // 则将Vector的全部元素都拷贝到数组a中。
325     System.arraycopy(elementData, 0, a, 0, elementCount);
326 
327         if (a.length > elementCount)
328             a[elementCount] = null;
329 
330         return a;
331     }
332 
333     // 获取index位置的元素
334     public synchronized E get(int index) {
335         if (index >= elementCount)
336             throw new ArrayIndexOutOfBoundsException(index);
337 
338         return (E)elementData[index];
339     }
340 
341     // 设置index位置的值为element。并返回index位置的原始值
342     public synchronized E set(int index, E element) {
343         if (index >= elementCount)
344             throw new ArrayIndexOutOfBoundsException(index);
345 
346         Object oldValue = elementData[index];
347         elementData[index] = element;
348         return (E)oldValue;
349     }
350 
351     // 将“元素e”添加到Vector最后。
352     public synchronized boolean add(E e) {
353         modCount++;
354         ensureCapacityHelper(elementCount + 1);
355         elementData[elementCount++] = e;
356         return true;
357     }
358 
359     // 删除Vector中的元素o
360     public boolean remove(Object o) {
361         return removeElement(o);
362     }
363 
364     // 在index位置添加元素element
365     public void add(int index, E element) {
366         insertElementAt(element, index);
367     }
368 
369     // 删除index位置的元素,并返回index位置的原始值
370     public synchronized E remove(int index) {
371         modCount++;
372         if (index >= elementCount)
373             throw new ArrayIndexOutOfBoundsException(index);
374         Object oldValue = elementData[index];
375 
376         int numMoved = elementCount - index - 1;
377         if (numMoved > 0)
378             System.arraycopy(elementData, index+1, elementData, index,
379                      numMoved);
380         elementData[--elementCount] = null; // Let gc do its work
381 
382         return (E)oldValue;
383     }
384 
385     // 清空Vector
386     public void clear() {
387         removeAllElements();
388     }
389 
390     // 返回Vector是否包含集合c
391     public synchronized boolean containsAll(Collection<?> c) {
392         return super.containsAll(c);
393     }
394 
395     // 将集合c添加到Vector中
396     public synchronized boolean addAll(Collection<? extends E> c) {
397         modCount++;
398         Object[] a = c.toArray();
399         int numNew = a.length;
400         ensureCapacityHelper(elementCount + numNew);
401         // 将集合c的全部元素拷贝到数组elementData中
402         System.arraycopy(a, 0, elementData, elementCount, numNew);
403         elementCount += numNew;
404         return numNew != 0;
405     }
406 
407     // 删除集合c的全部元素
408     public synchronized boolean removeAll(Collection<?> c) {
409         return super.removeAll(c);
410     }
411 
412     // 删除“非集合c中的元素”
413     public synchronized boolean retainAll(Collection<?> c)  {
414         return super.retainAll(c);
415     }
416 
417     // 从index位置开始,将集合c添加到Vector中
418     public synchronized boolean addAll(int index, Collection<? extends E> c) {
419         modCount++;
420         if (index < 0 || index > elementCount)
421             throw new ArrayIndexOutOfBoundsException(index);
422 
423         Object[] a = c.toArray();
424         int numNew = a.length;
425         ensureCapacityHelper(elementCount + numNew);
426 
427         int numMoved = elementCount - index;
428         if (numMoved > 0)
429             //先把带插入位置腾出来
430         System.arraycopy(elementData, index, elementData, index + numNew, numMoved);
431     //再把带插入元素插入到指定的位置区间
432         System.arraycopy(a, 0, elementData, index, numNew);
433         elementCount += numNew;
434         return numNew != 0;
435     }
436 
437     // 返回两个对象是否相等
438     public synchronized boolean equals(Object o) {
439         return super.equals(o);
440     }
441 
442     // 计算哈希值
443     public synchronized int hashCode() {
444         return super.hashCode();
445     }
446 
447     // 调用父类的toString()
448     public synchronized String toString() {
449         return super.toString();
450     }
451 
452     // 获取Vector中fromIndex(包括)到toIndex(不包括)的子集
453     public synchronized List<E> subList(int fromIndex, int toIndex) {
454         return Collections.synchronizedList(super.subList(fromIndex, toIndex), this);
455     }
456 
457     // 删除Vector中fromIndex到toIndex的元素
458     protected synchronized void removeRange(int fromIndex, int toIndex) {
459         modCount++;
460         int numMoved = elementCount - toIndex;
461         System.arraycopy(elementData, toIndex, elementData, fromIndex,
462                          numMoved);
463 
464         // 接下来把带删除元素全部赋值为空,以便于虚拟机进行垃圾回收
465         int newElementCount = elementCount - (toIndex-fromIndex);
466         while (elementCount != newElementCount)
467             elementData[--elementCount] = null;
468     }
469 
470     // java.io.Serializable的写入函数
471     private synchronized void writeObject(java.io.ObjectOutputStream s)
472         throws java.io.IOException {
473         s.defaultWriteObject();
474     }
475 }
View Code

总结:

  • Vector实际上是通过一个动态数组去保存数据的。当我们构造Vecotr时;若使用默认构造函数,则Vector的默认容量大小是10。
  • 当Vector容量不足以容纳全部元素时,Vector的容量会增加。若容量增加系数 >0,则将容量的值增加“容量增加系数”;否则,将容量大小增加一倍。
  • Vector的克隆函数,即是将全部元素克隆到一个数组中。
  • Vector在源代码中的一个匿名内部类来实现
 1  // 返回“Vector中全部元素对应的Enumeration”
 2     public Enumeration<E> elements() {
 3         // 通过匿名类方式实现Enumeration类
 4         return new Enumeration<E>() {
 5             int count = 0;
 6 
 7             // 是否存在下一个元素
 8             public boolean hasMoreElements() {
 9                 return count < elementCount;
10             }
11 
12             // 获取下一个元素
13             public E nextElement() {
14                 synchronized (Vector.this) {
15                     if (count < elementCount) {
16                         return (E)elementData[count++];
17                     }
18                 }
19                 throw new NoSuchElementException("Vector Enumeration");
20             }
21         };
22     }

4、Vector遍历方法

Vector支持4种遍历方式。建议使用下面的第二种去遍历Vector,因为效率问题。遍历Vector,使用索引的随机访问方式最快,使用迭代器最慢。

  • 通过迭代器遍历。即通过Iterator去遍历。
  • 随机访问,通过索引值去遍历。
  • 另一种for循环
  • Enumeration遍历。

5、Vector常用API的测试实例

Vector源码分析和实例应用Vector源码分析和实例应用
 1 import java.util.Vector;
 2 import java.util.List;
 3 import java.util.Iterator;
 4 import java.util.Enumeration;
 5 
 6 /**
 7  * @desc Vector测试函数:遍历Vector和常用API 
 8  *
 9  * @author skywang
10  */
11 public class VectorTest {
12     public static void main(String[] args) {
13         // 新建Vector
14         Vector vec = new Vector();
15             
16         // 添加元素
17         vec.add("1");
18         vec.add("2");
19         vec.add("3");
20         vec.add("4");
21         vec.add("5");
22 
23         // 设置第一个元素为100
24         vec.set(0, "100");
25         // 将“500”插入到第3个位置
26         vec.add(2, "300");
27         System.out.println("vec:"+vec);
28 
29         // (顺序查找)获取100的索引
30         System.out.println("vec.indexOf(100):"+vec.indexOf("100"));
31         // (倒序查找)获取100的索引
32         System.out.println("vec.lastIndexOf(100):"+vec.lastIndexOf("100"));
33         // 获取第一个元素
34         System.out.println("vec.firstElement():"+vec.firstElement());
35         // 获取第3个元素
36         System.out.println("vec.elementAt(2):"+vec.elementAt(2));
37         // 获取最后一个元素
38         System.out.println("vec.lastElement():"+vec.lastElement());
39 
40         // 获取Vector的大小
41         System.out.println("size:"+vec.size());
42         // 获取Vector的总的容量
43         System.out.println("capacity:"+vec.capacity());
44 
45         // 获取vector的“第2”到“第4”个元素
46         System.out.println("vec 2 to 4:"+vec.subList(1, 4));
47 
48         // 通过Enumeration遍历Vector
49         Enumeration enu = vec.elements();
50         while(enu.hasMoreElements())
51             System.out.println("nextElement():"+enu.nextElement());
52             
53         Vector retainVec = new Vector();
54         retainVec.add("100");
55         retainVec.add("300");
56         // 获取“vec”中包含在“retainVec中的元素”的集合
57         System.out.println("vec.retain():"+vec.retainAll(retainVec));
58         System.out.println("vec:"+vec);
59             
60         // 获取vec对应的String数组
61         String[] arr = (String[]) vec.toArray(new String[0]);
62         for (String str:arr)
63             System.out.println("str:"+str);
64 
65         // 清空Vector。clear()和removeAllElements()一样!
66         vec.clear();
67 //        vec.removeAllElements();
68 
69         // 判断Vector是否为空
70         System.out.println("vec.isEmpty():"+vec.isEmpty());
71     }   
72 }
View Code
 1 vec:[100, 2, 300, 3, 4, 5]
 2 vec.indexOf(100):0
 3 vec.lastIndexOf(100):0
 4 vec.firstElement():100
 5 vec.elementAt(2):300
 6 vec.lastElement():5
 7 size:6
 8 capacity:10
 9 vec 2 to 4:[2, 300, 3]
10 nextElement():100
11 nextElement():2
12 nextElement():300
13 nextElement():3
14 nextElement():4
15 nextElement():5
16 vec.retain():true
17 vec:[100, 300]
18 str:100
19 str:300
20 vec.isEmpty():true