JAVA源码解读之Vector

/**
 * The {@code Vector} class implements a growable array of
 * objects. Like an array, it contains components that can be
 * accessed using an integer index. However, the size of a
 * {@code Vector} can grow or shrink as needed to accommodate
 * adding and removing items after the {@code Vector} has been created.
 *
 * <p>Each vector tries to optimize storage management by maintaining a
 * {@code capacity} and a {@code capacityIncrement}. The
 * {@code capacity} is always at least as large as the vector
 * size; it is usually larger because as components are added to the
 * vector, the vector's storage increases in chunks the size of
 * {@code capacityIncrement}. An application can increase the
 * capacity of a vector before inserting a large number of
 * components; this reduces the amount of incremental reallocation.
 *
 * <p><a name="fail-fast"/>
 * The iterators returned by this class's {@link #iterator() iterator} and
 * {@link #listIterator(int) listIterator} methods are <em>fail-fast</em>:
 * if the vector is structurally modified at any time after the iterator is
 * created, in any way except through the iterator's own
 * {@link ListIterator#remove() remove} or
 * {@link ListIterator#add(Object) add} methods, the iterator will throw a
 * {@link ConcurrentModificationException}.  Thus, in the face of
 * concurrent modification, the iterator fails quickly and cleanly, rather
 * than risking arbitrary, non-deterministic behavior at an undetermined
 * time in the future.  The {@link Enumeration Enumerations} returned by
 * the {@link #elements() elements} method are <em>not</em> fail-fast.
 *
 * <p>Note that the fail-fast behavior of an iterator cannot be guaranteed
 * as it is, generally speaking, impossible to make any hard guarantees in the
 * presence of unsynchronized concurrent modification.  Fail-fast iterators
 * throw {@code ConcurrentModificationException} on a best-effort basis.
 * Therefore, it would be wrong to write a program that depended on this
 * exception for its correctness:  <i>the fail-fast behavior of iterators
 * should be used only to detect bugs.</i>
 *
 * <p>As of the Java 2 platform v1.2, this class was retrofitted to
 * implement the {@link List} interface, making it a member of the
 * <a href="{@docRoot}/../technotes/guides/collections/index.html">
 * Java Collections Framework</a>.  Unlike the new collection
 * implementations, {@code Vector} is synchronized.  If a thread-safe
 * implementation is not needed, it is recommended to use {@link
 * ArrayList} in place of {@code Vector}.
 *
 * @author  Lee Boynton
 * @author  Jonathan Payne
 * @see Collection
 * @see LinkedList
 * @since   JDK1.0
 */
  • Vector实现了一个可扩展的数组对象。和普通数组一样,它的元素可以通过整型下标访问得到。Vector被新建之后,其大小随着增加或删除元素而增长或减小。
  • 每一个vector通过容量和容量增长两个参数来优化平衡数组的大小。容量值至少和元素个数相同,但是容量值通常比元素个数大,因为会有元素增加到数组中,还有就是数组增长的幅度是以capacityIncrement为单位的。当插入大量的元素到数组中时,这个方法可以减少数组重置的次数。
  • “快失败准则”:如果此数组的迭代器被创建之后,数组结构依然在被改动,此刻迭代器将会抛出ConcurrentModificationException异常。遍历数组的另一个方法Enumerations,这个方法是没有执行“快失败准则”的。
  • 需要注意的是,迭代器的快失败行为不能保证同步修改安全。因此,凭借程序是否抛出这个异常来判别程序的准确性是不可取的。迭代器的快失败行为只能用来检验debug
  • 如果程序不要求是多线程安全的话,建议使用ArrayList而不是vector
    protected Object[] elementData;


注解字段:这个数组缓存vector中的所有元素,vector的容量和这个数组的大小是一样的,因此这个数组至少能容下vector的所有元素

    protected int elementCount;


注解字段:vector中合法元素的个数

    protected int capacityIncrement;

注解字段:当vector的元素个数大于capacity的时候,vector的capacity是自动增长的,扩容单位是capacityIncrement。如果初始化的时候这个值小于等于0,则当vector需要扩容的时候,扩容单位是当前capacity的二倍。

public Vector(int initialCapacity, int capacityIncrement) {
        super();
        if (initialCapacity < 0)
            throw new IllegalArgumentException("Illegal Capacity: "+
                                               initialCapacity);
        this.elementData = new Object[initialCapacity];
        this.capacityIncrement = capacityIncrement;
    }


注解方法:使用给定参数initialCapacity和capacityIncrement来构造一个空vector,如果初始容量低于0的时候,将会报出IllegalArgumentException异常

public Vector(int initialCapacity) {
        this(initialCapacity, 0);
    }


注解方法:使用给定参数initialCapacity和capacityIncrement=0来构造一个空vector。因为capacityIncrement=0,因此扩容的方法是当前容量*2。 同样的初始容量不能小于0

public Vector() {
        this(10);
    }


注解方法:构造一个初始容量是10,扩容方法是乘以2

 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来存放给定集合元素,细节方面主要是首先将集合转化为数组,将此数组的元素复制到给定初始数组中。

 public synchronized void copyInto(Object[] anArray) {
        System.arraycopy(elementData, 0, anArray, 0, elementCount);
    }


注解方法:将现有的vector中的元素全部复制到给定的数组中。

 

public synchronized void trimToSize() {
        modCount++;
        int oldCapacity = elementData.length;
        if (elementCount < oldCapacity) {
            elementData = Arrays.copyOf(elementData, elementCount);
        }
    }


注解方法:这个方法简单说就是保证咱vector占用最少存储空间,截取掉不需要的空间。

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


注解方法:这两个方法是判断vector是否需要扩容,minCapacity是现在vector需要的最小存储空间,elementData.length是当前vector的现有空间,如果需要的最小存储空间大于现有的空间时候,vector就需要扩容了。

private void grow(int minCapacity) {
        // overflow-conscious code
        int oldCapacity = elementData.length;
        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);
    }

    private static int hugeCapacity(int minCapacity) {
        if (minCapacity < 0) // overflow
            throw new OutOfMemoryError();
        return (minCapacity > MAX_ARRAY_SIZE) ?
            Integer.MAX_VALUE :
            MAX_ARRAY_SIZE;
    }


注解方法:这两个方法就是详细的扩容过程。首先获取当前的vector容量,然后根据参数capacityIncrement来决定扩容之后的容量(如果参数小于等于0,则扩容的速度是当前容量的二倍,否则则正常扩容,oldCapacity+capacityIncrement)。接下来,如果新的容量依旧低于vector需要的最低容量的时候,即将赋予新容量为真正需求容量。紧接着这种情况发生的概率很低,所以咱们可以直接忽视。最后和之前一样,将现有的元素全部复制到扩容后的vector中。

public synchronized void setSize(int newSize) {
        modCount++;
        if (newSize > elementCount) {
            ensureCapacityHelper(newSize);
        } else {
            for (int i = newSize ; i < elementCount ; i++) {
                elementData[i] = null;
            }
        }
        elementCount = newSize;
    }


注解方法:设置vector数组的大小,如果这个size大于现有的vector的大小,则将插入null填补空缺。如果现有元素的个数多余newSize的话,则将newSize后面的元素直接弃之。

public synchronized int capacity() {
        return elementData.length;
    }


注解方法:获取当前vector的容量

public synchronized int size() {
        return elementCount;
    }


注解方法:这是获取当前vector中元素的个数,和上一个方法一定要区别开来

public synchronized boolean isEmpty() {
        return elementCount == 0;
    }


注解方法:判断该vector是否没有元素

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 elementData(count++);
                    }
                }
                throw new NoSuchElementException("Vector Enumeration");
            }
        };
    }


注解方法:这是使用枚举的方法遍历vector的元素,需要注意的是这种方法不会产生快失败的行为。

public boolean contains(Object o) {
        return indexOf(o, 0) >= 0;
    }
 public int indexOf(Object o) {
        return indexOf(o, 0);
    }
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;
    }


注解方法:这三个方法要放在一起看,首先第一个方法是用来判断vector中是否存在给定元素,他所调用的方法是第二个方法。第二个方法是为了范围给定元素在vector中的位置,这个位置计算的方法是调用indexOf方法。我们来看看indexOf方法,首先如果给定元素是null,则遍历整个vector,如果存在直接返回位置,否则返回-1;如果给定元素不是null的话,同样遍历整个vector,返回给定元素的位置。这样再回到第一个方法,他是直接寻找给定元素在vector中的位置,如果位置为-1的话,直接告知调用者不存在这个元素,否则就返回true

public synchronized int lastIndexOf(Object o) {
        return lastIndexOf(o, elementCount-1);
    }
 public synchronized int lastIndexOf(Object o, int index) {
        if (index >= elementCount)
            throw new IndexOutOfBoundsException(index + " >= "+ elementCount);

        if (o == null) {
            for (int i = index; i >= 0; i--)
                if (elementData[i]==null)
                    return i;
        } else {
            for (int i = index; i >= 0; i--)
                if (o.equals(elementData[i]))
                    return i;
        }
        return -1;
    }

注解方法:先说第二个方法吧,给定两个参数其中index是指从vector中的index位置,开始向前遍历vector,查看最后一次出现object的位置,如果不存在则返回-1.然后第一个方法就好理解了,它是在整个vector中搜索object最后一次出现的位置。需要注意的是其中index如果大于等于vector中元素的个数,就会抛出数组越界的异常。

public synchronized E elementAt(int index) {
        if (index >= elementCount) {
            throw new ArrayIndexOutOfBoundsException(index + " >= " + elementCount);
        }

        return elementData(index);
    }


注解方法:输出vector中给定位置的元素,首先也是会判断index是否越界

public synchronized E firstElement() {
        if (elementCount == 0) {
            throw new NoSuchElementException();
        }
        return elementData(0);
    }


注解方法:输出vector中第一个元素,如果vector中没有元素,则会抛出异常

 public synchronized E lastElement() {
        if (elementCount == 0) {
            throw new NoSuchElementException();
        }
        return elementData(elementCount - 1);
    }


注解方法:输出vector中最后一个元素,同样,如果vector中没有元素,也会抛出异常

public synchronized void setElementAt(E obj, int index) {
        if (index >= elementCount) {
            throw new ArrayIndexOutOfBoundsException(index + " >= " +
                                                     elementCount);
        }
        elementData[index] = obj;
    }


注解方法:将index位置上元素,替换为指定元素。首先也要判断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位置上的元素。首先判断index是否越界,越界则抛出异常。如果没有越界的话,则删除index位置的元素,并将index位置后面的元素全往前复制一个位置,并且将最后一个位置设置为null

 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++;
    }


注解方法:在指定位置插入元素。如果插入的位置大于元素的个数,就会抛出异常。因为要插入元素,所以首先要做的就是扩容判断的相关操作,前面已经介绍过了。然后将vector的元素从index位置全部向后复制,然后index位置设置为指定元素。

public synchronized void addElement(E obj) {
        modCount++;
        ensureCapacityHelper(elementCount + 1);
        elementData[elementCount++] = obj;
    }


注解方法:在vector的最后一个位置插入元素。同样的,在插入之前也执行扩容判断的相关操作。

public synchronized boolean removeElement(Object obj) {
        modCount++;
        int i = indexOf(obj);
        if (i >= 0) {
            removeElementAt(i);
            return true;
        }
        return false;
    }


注解方法:是否可以移除指定的元素。首先调用之前的indexOf方法,获取obj的位置,如果存在这个位置,则调用removeElementAt方法,直接移除该元素,然后返回true。否则就会返回false

public synchronized void removeAllElements() {
        modCount++;
        // Let gc do its work
        for (int i = 0; i < elementCount; i++)
            elementData[i] = null;

        elementCount = 0;
    }


方法注解:移除vector的所有元素。将所有的元素置为null,然后垃圾回收器会回收他,最后别忘记vector中元素个数为0

public synchronized E get(int index) {         if (index >= elementCount)             throw new ArrayIndexOutOfBoundsException(index);

        return elementData(index);     }

注解方法:返回指定位置的元素。首先会判断指定位置是否越界

public synchronized E set(int index, E element) {
        if (index >= elementCount)
            throw new ArrayIndexOutOfBoundsException(index);

        E oldValue = elementData(index);
        elementData[index] = element;
        return oldValue;
    }


注解方法:用特定元素取代特定位置的元素,并返回旧值。需要注意的是,只要用到位置的地方,都需要判断位置是否出现异常

public synchronized boolean add(E e) {
        modCount++;
        ensureCapacityHelper(elementCount + 1);
        elementData[elementCount++] = e;
        return true;
    }


注解方法:在vector最后添加元素。首先进行扩容判断处理,然后在最后添加元素。

public boolean remove(Object o) {
        return removeElement(o);
    }


注解方法:判断是否可以移除vector中的指定元素,如果有多个这个元素,则移除元素在vector中第一次出现的地方

public void add(int index, E element) {
        insertElementAt(element, index);
    }


注解方法:在指定位置添加指定元素。调用的insertElementAt方法

public synchronized E remove(int index) {
        modCount++;
        if (index >= elementCount)
            throw new ArrayIndexOutOfBoundsException(index);
        E 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 oldValue;
    }


注解方法:移除指定位置的元素,并返回该值。所有也会判断index是否数组越界。移除某个元素之后,将此位置之后的元素全部向前复制一个位置,并将最后一个位置置为null,交给垃圾回收器回收。

public void clear() {
        removeAllElements();
    }


注解方法:调用removeAllElements方法,清除vector所有元素

public synchronized boolean containsAll(Collection<?> c) {
        return super.containsAll(c);
    }


注解方法:判断vector中是否包含指定集合中的所有元素。调用父类中的containsAll方法,这个方法是逐个判断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;
    }


注解方法:在vector中的index处,插入指定集合的所有元素。首先这个方法会判断index是否越界,然后将集合转化为数组,先扩容机制检查,然后将vector中从index位置到最后的元素全部复制到新数组的index+numNew到最后的位置。然后再复制给定集合到新vector的index到index+numNew位置。

 





 

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Narasimha_Karumanchi

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值