JAVA源码解读之Vector

来源:互联网 发布:vm14安装ubuntu 教程 编辑:程序博客网 时间:2024/04/30 14:17
/** * 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 0
原创粉丝点击