美文网首页
Collection-Vector

Collection-Vector

作者: 小程有话说 | 来源:发表于2016-11-10 13:31 被阅读45次

    jdk版本:1.8.0_77
    参考文档:jdk 1.8 docs

    Vector类图

    Vector继承关系

    Vector特点

    1. Vector对象内部维护一个数组对象,可以通过整数索引访问数组元素。
    protected Object[] elementData;//存储对象的数组缓冲区
    protected int elementCount;//Vector存储的元素个数
    protected int capacityIncrement;//当Vector容量不够扩容大小
    
    1. Vector通过设置capacity、capacityIncrement参数来优化存储管理;capacity等于数组长度,当Vector数组不够用时扩容,扩容大小默认是capacityIncrement(如果该参数为0则当前数组长度*2处理)。
        @Test
        public void testCapacity() {
            //Vector扩容是在内部数组放满之后调用grow
            //扩容方式分2种:1.数组容量*2处理;2.数组容量变为newCapacity=oldCapacity+capacityIncrement
            Vector v1 = new Vector(1);
            Vector v2 = new Vector(1, 1);//如果设置capacityIncrement则按照第二种方式扩容
            System.out.println("v1 capacity:" + v1.capacity() + "|v2 capacity:" + v2.capacity());
            v1.add("1");
            v2.add("1");
            v1.add("2");
            v2.add("2");
            System.out.println("v1 capacity:" + v1.capacity() + "|v2 capacity:" + v2.capacity());
            v1.add("3");
            v2.add("3");
            System.out.println("v1 capacity:" + v1.capacity() + "|v2 capacity:" + v2.capacity());
        }
    

    运行结果:

    v1 capacity:1|v2 capacity:1
    v1 capacity:2|v2 capacity:2
    v1 capacity:4|v2 capacity:3
    

    v1、v2初始容量capacity均为1,v2设置capacityIncrement为1;v1每次扩容为原来容量1倍,v2每次扩容capacityIncrement大小。

        private void grow(int minCapacity) {//扩容方法源代码
            // overflow-conscious code
            int oldCapacity = elementData.length;
            //根据capacityIncrement是否存在选择扩容方式
            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);
        }
    
    1. Vector数组容量可以�自动扩容和手动缩容以便适应Vector创建之后�数组大小变化。
        @Test
        public void testCapcityIncrementAndReduce() {
            Vector v1 = new Vector(0, 10);
            System.out.println("v1 capcity:" + v1.capacity());
            v1.add("1");
            System.out.println("v1 capcity:" + v1.capacity());
            v1.trimToSize();
            System.out.println("v1 capcity:" + v1.capacity());
        }
    

    运行结果:

    v1 capcity:0
    v1 capcity:10
    v1 capcity:1
    
        public synchronized boolean add(E e) {//add方法源代码
            modCount++;
            ensureCapacityHelper(elementCount + 1);
            elementData[elementCount++] = e;
            return true;
        }
        public synchronized void trimToSize() {//缩容源代码
            modCount++;
            int oldCapacity = elementData.length;
            if (elementCount < oldCapacity) {
                elementData = Arrays.copyOf(elementData, elementCount);
            }
        }
    

    可以通过trimToSize方法减少Vector所占用空间。

    1. 如果在Vector集合迭代时集合中添加或删除元素(数组结构改变了),Vector迭代器迭代会fail-fast(快速失败),迭代方法抛出ConcurrentModificationException异常。
        @Test
        public void testFailFast() throws InterruptedException {
            //fail-fast 当遍历Iterator对象时如果此时对数组做增/删操作,抛出异常
            Vector v1 = new Vector();
            v1.add("a");
            v1.add("b");
            v1.add("c");
            Iterator it = v1.iterator();
            new Thread(() -> {
                try {
                    Thread.sleep(1000l);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                v1.remove("c");
                System.out.println("v1 remove one element");
            }).start();
            while (it.hasNext()) {
                Object next = it.next();
                System.out.println("v1:" + next);
                Thread.sleep(3000l);
            }
        }
    

    运行结果:

    v1:a
    v1 remove one element
    java.util.ConcurrentModificationException
    

    当正在迭代v1时,我们v1做删除或添加操作,抛出异常。

            final void checkForComodification() {//modCount在每次对象结果变化时+1
                if (modCount != expectedModCount)
                    throw new ConcurrentModificationException();
            }
    

    避免出现该问题方法:

        @Test
        public void testClone() throws InterruptedException {
            //假设有多个线程同时操作一个Vector对象,如果此时需要对Vector遍历,需要先clone该对象,这样就能避免在迭代时其他线程操作对象导致迭代失败
            //Vector是线程安全的
            Vector v1 = new Vector();
            v1.add("a");
            v1.add("b");
            v1.add("c");
            Vector v2 = (Vector) v1.clone();
            Iterator it = v1.iterator();
            new Thread(() -> {
                try {
                    Thread.sleep(1000l);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                v2.remove("c");
                System.out.println("v2 remove");
            }).start();
            while (it.hasNext()) {
                Object next = it.next();
                System.out.println("v1:" + next);
                Thread.sleep(3000l);
            }
        }
    

    运行结果:

    v1:a
    v2 remove
    v1:b
    v1:c
    

    当我们要迭代一个v1时先调用clone()方法克隆出v2,对v2迭代。

        public synchronized Object clone() {
            try {
                @SuppressWarnings("unchecked")
                    Vector<E> v = (Vector<E>) super.clone();
                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(e);
            }
        }
    
    1. Vector是线程安全的;如果不需要线程安全,可以使用ArrayList代替Vector。
    public synchronized void addElement(E obj) {}
    public synchronized boolean removeElement(Object obj) {}
    public synchronized void removeAllElements() {}
    ...
    

    方法加上synchronized关键字来保证线程之间同步。


    代码

    相关文章

      网友评论

          本文标题:Collection-Vector

          本文链接:https://www.haomeiwen.com/subject/kagtpttx.html