zoukankan      html  css  js  c++  java
  • Vector源码分析和实例应用

    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的数据结构和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源码分析

      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的测试实例

     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
  • 相关阅读:
    JQuery优化之 -- 正确使用选择器
    Vue计算属性methords 与 computed 的区别
    HTML中常用字符实体
    SQL复习(w3school)笔记
    AndroidStudio中使用AndroidAnnotations时,build.gradle的配置
    JAVA的第一次作业
    input标签submit属性,用CSS控制样式时高度不好控制的解决办法
    微信小程序开发五:案例实践
    微信小程序开发四:接口
    微信小程序开发三:组件
  • 原文地址:https://www.cnblogs.com/BaoZiY/p/10658445.html
Copyright © 2011-2022 走看看