zoukankan      html  css  js  c++  java
  • 5,Vector

    一,Vector简介

       

    1,Vector 是矢量队列,它是JDK1.0版本添加的类。

    2,Vector 继承了AbstractList实现了List;所以,它是一个队列,支持相关的添加、删除、修改、遍历等功能。

    3,Vector 实现了RandmoAccess接口,即提供了随机访问功能。

    4,Vector 实现了Cloneable接口,即实现clone()函数。它能被克隆。

    5,Vector 实现Serializable接口,说明Vector支持序列化

    6,Vector 与ArrayList不同,Vector中的操作是线程安全的

    二,数据结构

    Vector的数据结构如下:

    底层的数据结构就是数组,数组元素类型为Object类型,即可以存放所有类型数据。对Vector类的实例的所有的操作底层都是基于数组的。

    三,Vector源码

    1,Vector结构

    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;
        
        省略......
    }

    1.1,elementData对象

    elementData是Object[] 类型的数组,它保存了添加到Vector中的元素。

    elementData是个动态数组,如果初始化Vector时,没指定动态数组的大小,则使用默认大小10。

    随着Vector中元素的增加,Vector的容量也会动态增长,capacityIncrement是与容量增长相关的增长系数,具体的增长方式,请参考ensureCapacity()函数。

    1.2,elementCount

    动态数组的实际大小。

    1.3,capacityIncrement

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

    2,构造函数

    Vector提供了四种方式的构造器,如下:

    //创建指定容量大小的数组,设置增长量。
    public Vector(int initialCapacity, int capacityIncrement) {
        super();
        if (initialCapacity < 0)
            throw new IllegalArgumentException("Illegal Capacity: "+
                                               initialCapacity);
        this.elementData = new Object[initialCapacity];
        //设置增长量。
        this.capacityIncrement = capacityIncrement;
    }
     
    //创建一个用户指定容量的数组,同时增长量为 0
    public Vector(int initialCapacity) {
        this(initialCapacity, 0);
    }
     
    //创建默认容量 10 的数组,同时增长量为 0 
    public Vector() {
        this(10);
    }
     
    //创建一个包含指定集合的数组
    public Vector(Collection<? extends E> c) {
        //转成数组,赋值
        elementData = c.toArray();
        elementCount = elementData.length;
        // c.toArray might (incorrectly) not return Object[] (see 6260652)
        //可能有这个神奇的 bug,用 Arrays.copyOf 重新创建、复制
        if (elementData.getClass() != Object[].class)
            elementData = Arrays.copyOf(elementData, elementCount, Object[].class);
    }

    3,部分函数

    3.1,add()函数

    public synchronized boolean add(E e) {
        modCount++;
        ensureCapacityHelper(elementCount + 1);
        elementData[elementCount++] = e;
        return true;
    }
    // 将e添加到ArrayList的指定位置
    public void add(int index, E element) {
        insertElementAt(element, index);
    }

    在add函数发现其调用了函数ensureCapacityHelper,ensureCapacityHelper的具体函数如下:

    private void ensureCapacityHelper(int minCapacity) {
        // overflow-conscious code
        if (minCapacity - elementData.length > 0)
            grow(minCapacity);
    }

    在ensureCapacityHelper函数发现其调用了函数grow,grow函数才会对数组进行扩容,grow函数的具体函数如下:

    private void grow(int minCapacity) {
        int oldCapacity = elementData.length;// 旧容量
        //若容量增加系数 >0,则将容量的值增加“容量增加系数”;否则,将容量大小增加一倍。
        int newCapacity = oldCapacity + ((capacityIncrement > 0) ?
                                         capacityIncrement : oldCapacity);
        // 判断新容量小于参数指定容量,修改新容量
        if (newCapacity - minCapacity < 0)
            newCapacity = minCapacity;
        // 判断新容量大于最大容量
        if (newCapacity - MAX_ARRAY_SIZE > 0)
            newCapacity = hugeCapacity(minCapacity);// 指定新容量,特殊情况下(新扩展数组大小已经达到了最大值)则只取最大值。
        // 拷贝扩容
        elementData = Arrays.copyOf(elementData, newCapacity);
    }

    3.2,subList()函数

    //返回指定区间的线程安全的List
    public synchronized List<E> subList(int fromIndex, int toIndex) {
        return Collections.synchronizedList(super.subList(fromIndex, toIndex),
                                            this);
    }

    Collections.synchronizedList封装是对List对象添加同步锁,各方法本质上还是调用的List的方法。Vector类其他方法和ArrayList差不多,无非加上了一个synchronized同步处理,这里就不再赘述了。

    四,Vector遍历方式

    Vector支持4种遍历方式。

    1,迭代器遍历

    Iterator<String> iter = listVector.iterator();
    while (iter.hasNext()) {
        System.out.println(iter.next());
    }

    2,随机访问,通过索引值去遍历。

    由于Vector实现了RandomAccess接口,它支持通过索引值去随机访问元素。

    for (int i = 0; i < listVector.size(); i++) {
        System.out.println(listVector.get(i));
    }

    3,for循环遍历

    for (String string : listVector) {
        System.out.println(string);
    }

    4,Enumeration遍历

    Enumeration<String> enu = listVector.elements();
    while (enu.hasMoreElements()) {
        String string = (String) enu.nextElement();
        System.out.println(string);
    }

    下面通过一个实例,比较这4种方式的效率,代码如下:

    public class TestVector {
        static long startTime = 0;
        static long endTime = 0;
        
        public static void main(String[] args) {
            Vector<String> listVector = new Vector<String>();
            
            for (int i = 0; i < 100000; i++) {
                listVector.add(i + "");
            }
            TestVector.loopVector_Indexes(listVector);
            TestVector.loopVector_Iterator(listVector);
            TestVector.loopVector_For(listVector);
            TestVector.loopVector_Enumeration(listVector);
        }
        
        //随机访问,通过索引值去遍历。
        public static void loopVector_Indexes(Vector<String> listVector){
            startTime = System.currentTimeMillis();
            for (int i = 0; i < listVector.size(); i++) {
                listVector.get(i);
            }
            endTime = System.currentTimeMillis();
            long interval = endTime - startTime;
            System.out.println("随机访问,通过索引值去遍历(loopVector_Indexes):" + interval + " ms");
        }
        
        //通过迭代器遍历
        public static void loopVector_Iterator(Vector<String> listVector){
            startTime = System.currentTimeMillis();
            for (Iterator<String> iter = listVector.iterator(); iter.hasNext();) {
                iter.next();
            }
            endTime = System.currentTimeMillis();
            long interval = endTime - startTime;
            System.out.println("通过迭代器遍历(loopVector_Iterator):" + interval + " ms");
        }
        
        //通过for循环遍历
        public static void loopVector_For(Vector<String> listVector){
            startTime = System.currentTimeMillis();
            String tString;
            for (String string : listVector) {
                tString = string;
            }
            endTime = System.currentTimeMillis();
            long interval = endTime - startTime;
            System.out.println("通过for循环遍历(loopVector_For):" + interval + " ms");
        }
        
        //Enumeration遍历
        public static void loopVector_Enumeration(Vector<String> listVector){
            startTime = System.currentTimeMillis();
            Enumeration<String> enu = listVector.elements();
            String tString;
            while (enu.hasMoreElements()) {
                tString = (String)enu.nextElement();
            }
            endTime = System.currentTimeMillis();
            long interval = endTime - startTime;
            System.out.println("通过Enumeration遍历(loopVector_Enumeration):" + interval + " ms");
        }
    }

    运行结果:

    遍历Vector,使用索引的随机访问方式最快。

    五,常用函数

    // 将数组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) {
        if (minCapacity - elementData.length > 0)
            grow(minCapacity);
    }
     
    // 确定Vector的容量。
    public synchronized void ensureCapacity(int minCapacity) {
        // 将Vector的改变统计数+1
        modCount++;
        ensureCapacityHelper(minCapacity);
    }
     
    private void grow(int minCapacity) {
        int oldCapacity = elementData.length;// 旧容量
        //若容量增加系数 >0,则将容量的值增加“容量增加系数”;否则,将容量大小增加一倍。
        int newCapacity = oldCapacity + ((capacityIncrement > 0) ?
                                         capacityIncrement : oldCapacity);
        // 判断新容量小于参数指定容量,修改新容量
        if (newCapacity - minCapacity < 0)
            newCapacity = minCapacity;
        // 判断新容量大于最大容量
        if (newCapacity - MAX_ARRAY_SIZE > 0)
            newCapacity = hugeCapacity(minCapacity);// 指定新容量,特殊情况下(新扩展数组大小已经达到了最大值)则只取最大值。
        // 拷贝扩容
        elementData = Arrays.copyOf(elementData, newCapacity);
    }
     
    // 设置容量值为 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();
    }
    常用函数注解
  • 相关阅读:
    BZOJ 2142: 礼物
    八校联考前3场记录
    BZOJ1115:[POI2009]石子游戏Kam (博弈论)
    IE10、IE11解决不能播放Flash的问题!
    ClientAbortException 异常解决办法
    WeX5学习笔记-建立项目且从SVN获取版本
    WeX5学习笔记-创建本地APP相关问题
    android 常见分辨率(mdpi、hdpi 、xhdpi、xxhdpi )屏幕适配
    ERROR 1130 (HY000):Host'localhost'解决方法
    一台机器运行多个JBoss 4.2.3多实例,或多个同一版
  • 原文地址:https://www.cnblogs.com/Zender/p/8119297.html
Copyright © 2011-2022 走看看