Vector 源码

来源:互联网 发布:java含金量高的证书 编辑:程序博客网 时间:2024/06/11 04:55

1、Vector扩容机制

Vector有个capacityIncrement来记录每次扩容的容量,默认为0,初始化的时候可以指定,默认的扩容是每次添加一倍容量

每次添加元素前先检查是否需要扩容

    //扩容每一次添加的容量     protected int capacityIncrement;     public Vector(int initialCapacity, int capacityIncrement) {        super();        if (initialCapacity < 0)            throw new IllegalArgumentException("Illegal Capacity: "+                                               initialCapacity);        this.elementData = new Object[initialCapacity];        this.capacityIncrement = capacityIncrement;    }     //初始化为10个容量    public Vector() {        this(10);    }    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);    }

2、源代码(代码跟ArrayList差不多,只是因为Vector是线程安全的,每个方法都会加上synchronized,代码中不再添加注释)

/* * Copyright (c) 1994, 2013, Oracle and/or its affiliates. All rights reserved. * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. * * * * * * * * * * * * * * * * * * * * */package java.util;import java.util.function.Consumer;import java.util.function.Predicate;import java.util.function.UnaryOperator;/** * 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></a>: * 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 */public class Vector<E>    extends AbstractList<E>    implements List<E>, RandomAccess, Cloneable, java.io.Serializable{    /**     * The array buffer into which the components of the vector are     * stored. The capacity of the vector is the length of this array buffer,     * and is at least large enough to contain all the vector's elements.     *     * <p>Any array elements following the last element in the Vector are null.     *     * @serial     */    //存储元素的缓冲    protected Object[] elementData;    /**     * The number of valid components in this {@code Vector} object.     * Components {@code elementData[0]} through     * {@code elementData[elementCount-1]} are the actual items.     *     * @serial     */    //元素个数    protected int elementCount;    /**     * The amount by which the capacity of the vector is automatically     * incremented when its size becomes greater than its capacity.  If     * the capacity increment is less than or equal to zero, the capacity     * of the vector is doubled each time it needs to grow.     *     * @serial     */    //扩容每一次添加的容量    protected int capacityIncrement;    /** use serialVersionUID from JDK 1.0.2 for interoperability */    private static final long serialVersionUID = -2767605614048989439L;    /**     * Constructs an empty vector with the specified initial capacity and     * capacity increment.     *     * @param   initialCapacity     the initial capacity of the vector     * @param   capacityIncrement   the amount by which the capacity is     *                              increased when the vector overflows     * @throws IllegalArgumentException if the specified initial capacity     *         is negative     */    public Vector(int initialCapacity, int capacityIncrement) {        super();        if (initialCapacity < 0)            throw new IllegalArgumentException("Illegal Capacity: "+                                               initialCapacity);        this.elementData = new Object[initialCapacity];        this.capacityIncrement = capacityIncrement;    }    /**     * Constructs an empty vector with the specified initial capacity and     * with its capacity increment equal to zero.     *     * @param   initialCapacity   the initial capacity of the vector     * @throws IllegalArgumentException if the specified initial capacity     *         is negative     */    public Vector(int initialCapacity) {        this(initialCapacity, 0);    }    /**     * Constructs an empty vector so that its internal data array     * has size {@code 10} and its standard capacity increment is     * zero.     */    //初始化为10个容量    public Vector() {        this(10);    }    /**     * Constructs a vector containing the elements of the specified     * collection, in the order they are returned by the collection's     * iterator.     *     * @param c the collection whose elements are to be placed into this     *       vector     * @throws NullPointerException if the specified collection is null     * @since   1.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);    }    /**     * Copies the components of this vector into the specified array.     * The item at index {@code k} in this vector is copied into     * component {@code k} of {@code anArray}.     *     * @param  anArray the array into which the components get copied     * @throws NullPointerException if the given array is null     * @throws IndexOutOfBoundsException if the specified array is not     *         large enough to hold all the components of this vector     * @throws ArrayStoreException if a component of this vector is not of     *         a runtime type that can be stored in the specified array     * @see #toArray(Object[])     */    public synchronized void copyInto(Object[] anArray) {        System.arraycopy(elementData, 0, anArray, 0, elementCount);    }    /**     * Trims the capacity of this vector to be the vector's current     * size. If the capacity of this vector is larger than its current     * size, then the capacity is changed to equal the size by replacing     * its internal data array, kept in the field {@code elementData},     * with a smaller one. An application can use this operation to     * minimize the storage of a vector.     */    public synchronized void trimToSize() {        modCount++;        int oldCapacity = elementData.length;        if (elementCount < oldCapacity) {            elementData = Arrays.copyOf(elementData, elementCount);        }    }    /**     * Increases the capacity of this vector, if necessary, to ensure     * that it can hold at least the number of components specified by     * the minimum capacity argument.     *     * <p>If the current capacity of this vector is less than     * {@code minCapacity}, then its capacity is increased by replacing its     * internal data array, kept in the field {@code elementData}, with a     * larger one.  The size of the new data array will be the old size plus     * {@code capacityIncrement}, unless the value of     * {@code capacityIncrement} is less than or equal to zero, in which case     * the new capacity will be twice the old capacity; but if this new size     * is still smaller than {@code minCapacity}, then the new capacity will     * be {@code minCapacity}.     *     * @param minCapacity the desired minimum capacity     */    public synchronized void ensureCapacity(int minCapacity) {        if (minCapacity > 0) {            modCount++;            ensureCapacityHelper(minCapacity);        }    }    /**     * This implements the unsynchronized semantics of ensureCapacity.     * Synchronized methods in this class can internally call this     * method for ensuring capacity without incurring the cost of an     * extra synchronization.     *     * @see #ensureCapacity(int)     */    private void ensureCapacityHelper(int minCapacity) {        // overflow-conscious code        if (minCapacity - elementData.length > 0)            grow(minCapacity);    }    /**     * The maximum size of array to allocate.     * Some VMs reserve some header words in an array.     * Attempts to allocate larger arrays may result in     * OutOfMemoryError: Requested array size exceeds VM limit     */    private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;    //扩容机制    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;    }    /**     * Sets the size of this vector. If the new size is greater than the     * current size, new {@code null} items are added to the end of     * the vector. If the new size is less than the current size, all     * components at index {@code newSize} and greater are discarded.     *     * @param  newSize   the new size of this vector     * @throws ArrayIndexOutOfBoundsException if the new size is negative     */    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;    }    /**     * Returns the current capacity of this vector.     *     * @return  the current capacity (the length of its internal     *          data array, kept in the field {@code elementData}     *          of this vector)     */    public synchronized int capacity() {        return elementData.length;    }    /**     * Returns the number of components in this vector.     *     * @return  the number of components in this vector     */    public synchronized int size() {        return elementCount;    }    /**     * Tests if this vector has no components.     *     * @return  {@code true} if and only if this vector has     *          no components, that is, its size is zero;     *          {@code false} otherwise.     */    public synchronized boolean isEmpty() {        return elementCount == 0;    }    /**     * Returns an enumeration of the components of this vector. The     * returned {@code Enumeration} object will generate all items in     * this vector. The first item generated is the item at index {@code 0},     * then the item at index {@code 1}, and so on.     *     * @return  an enumeration of the components of this vector     * @see     Iterator     */    //返回枚举元素    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");            }        };    }    /**     * Returns {@code true} if this vector contains the specified element.     * More formally, returns {@code true} if and only if this vector     * contains at least one element {@code e} such that     * <tt>(o==null ? e==null : o.equals(e))</tt>.     *     * @param o element whose presence in this vector is to be tested     * @return {@code true} if this vector contains the specified element     */    public boolean contains(Object o) {        return indexOf(o, 0) >= 0;    }    /**     * Returns the index of the first occurrence of the specified element     * in this vector, or -1 if this vector does not contain the element.     * More formally, returns the lowest index {@code i} such that     * <tt>(o==null ? get(i)==null : o.equals(get(i)))</tt>,     * or -1 if there is no such index.     *     * @param o element to search for     * @return the index of the first occurrence of the specified element in     *         this vector, or -1 if this vector does not contain the element     */    public int indexOf(Object o) {        return indexOf(o, 0);    }    /**     * Returns the index of the first occurrence of the specified element in     * this vector, searching forwards from {@code index}, or returns -1 if     * the element is not found.     * More formally, returns the lowest index {@code i} such that     * <tt>(i >= index && (o==null ? get(i)==null : o.equals(get(i))))</tt>,     * or -1 if there is no such index.     *     * @param o element to search for     * @param index index to start searching from     * @return the index of the first occurrence of the element in     *         this vector at position {@code index} or later in the vector;     *         {@code -1} if the element is not found.     * @throws IndexOutOfBoundsException if the specified index is negative     * @see     Object#equals(Object)     */    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;    }    /**     * Returns the index of the last occurrence of the specified element     * in this vector, or -1 if this vector does not contain the element.     * More formally, returns the highest index {@code i} such that     * <tt>(o==null ? get(i)==null : o.equals(get(i)))</tt>,     * or -1 if there is no such index.     *     * @param o element to search for     * @return the index of the last occurrence of the specified element in     *         this vector, or -1 if this vector does not contain the element     */    public synchronized int lastIndexOf(Object o) {        return lastIndexOf(o, elementCount-1);    }    /**     * Returns the index of the last occurrence of the specified element in     * this vector, searching backwards from {@code index}, or returns -1 if     * the element is not found.     * More formally, returns the highest index {@code i} such that     * <tt>(i <= index && (o==null ? get(i)==null : o.equals(get(i))))</tt>,     * or -1 if there is no such index.     *     * @param o element to search for     * @param index index to start searching backwards from     * @return the index of the last occurrence of the element at position     *         less than or equal to {@code index} in this vector;     *         -1 if the element is not found.     * @throws IndexOutOfBoundsException if the specified index is greater     *         than or equal to the current size of this vector     */    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;    }    /**     * Returns the component at the specified index.     *     * <p>This method is identical in functionality to the {@link #get(int)}     * method (which is part of the {@link List} interface).     *     * @param      index   an index into this vector     * @return     the component at the specified index     * @throws ArrayIndexOutOfBoundsException if the index is out of range     *         ({@code index < 0 || index >= size()})     */    public synchronized E elementAt(int index) {        if (index >= elementCount) {            throw new ArrayIndexOutOfBoundsException(index + " >= " + elementCount);        }        return elementData(index);    }    /**     * Returns the first component (the item at index {@code 0}) of     * this vector.     *     * @return     the first component of this vector     * @throws NoSuchElementException if this vector has no components     */    public synchronized E firstElement() {        if (elementCount == 0) {            throw new NoSuchElementException();        }        return elementData(0);    }    /**     * Returns the last component of the vector.     *     * @return  the last component of the vector, i.e., the component at index     *          <code>size() - 1</code>.     * @throws NoSuchElementException if this vector is empty     */    public synchronized E lastElement() {        if (elementCount == 0) {            throw new NoSuchElementException();        }        return elementData(elementCount - 1);    }    /**     * Sets the component at the specified {@code index} of this     * vector to be the specified object. The previous component at that     * position is discarded.     *     * <p>The index must be a value greater than or equal to {@code 0}     * and less than the current size of the vector.     *     * <p>This method is identical in functionality to the     * {@link #set(int, Object) set(int, E)}     * method (which is part of the {@link List} interface). Note that the     * {@code set} method reverses the order of the parameters, to more closely     * match array usage.  Note also that the {@code set} method returns the     * old value that was stored at the specified position.     *     * @param      obj     what the component is to be set to     * @param      index   the specified index     * @throws ArrayIndexOutOfBoundsException if the index is out of range     *         ({@code index < 0 || index >= size()})     */    public synchronized void setElementAt(E obj, int index) {        if (index >= elementCount) {            throw new ArrayIndexOutOfBoundsException(index + " >= " +                                                     elementCount);        }        elementData[index] = obj;    }    /**     * Deletes the component at the specified index. Each component in     * this vector with an index greater or equal to the specified     * {@code index} is shifted downward to have an index one     * smaller than the value it had previously. The size of this vector     * is decreased by {@code 1}.     *     * <p>The index must be a value greater than or equal to {@code 0}     * and less than the current size of the vector.     *     * <p>This method is identical in functionality to the {@link #remove(int)}     * method (which is part of the {@link List} interface).  Note that the     * {@code remove} method returns the old value that was stored at the     * specified position.     *     * @param      index   the index of the object to remove     * @throws ArrayIndexOutOfBoundsException if the index is out of range     *         ({@code index < 0 || index >= size()})     */    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 */    }    /**     * Inserts the specified object as a component in this vector at the     * specified {@code index}. Each component in this vector with     * an index greater or equal to the specified {@code index} is     * shifted upward to have an index one greater than the value it had     * previously.     *     * <p>The index must be a value greater than or equal to {@code 0}     * and less than or equal to the current size of the vector. (If the     * index is equal to the current size of the vector, the new element     * is appended to the Vector.)     *     * <p>This method is identical in functionality to the     * {@link #add(int, Object) add(int, E)}     * method (which is part of the {@link List} interface).  Note that the     * {@code add} method reverses the order of the parameters, to more closely     * match array usage.     *     * @param      obj     the component to insert     * @param      index   where to insert the new component     * @throws ArrayIndexOutOfBoundsException if the index is out of range     *         ({@code index < 0 || index > size()})     */    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++;    }    /**     * Adds the specified component to the end of this vector,     * increasing its size by one. The capacity of this vector is     * increased if its size becomes greater than its capacity.     *     * <p>This method is identical in functionality to the     * {@link #add(Object) add(E)}     * method (which is part of the {@link List} interface).     *     * @param   obj   the component to be added     */    public synchronized void addElement(E obj) {        modCount++;        ensureCapacityHelper(elementCount + 1);        elementData[elementCount++] = obj;    }    /**     * Removes the first (lowest-indexed) occurrence of the argument     * from this vector. If the object is found in this vector, each     * component in the vector with an index greater or equal to the     * object's index is shifted downward to have an index one smaller     * than the value it had previously.     *     * <p>This method is identical in functionality to the     * {@link #remove(Object)} method (which is part of the     * {@link List} interface).     *     * @param   obj   the component to be removed     * @return  {@code true} if the argument was a component of this     *          vector; {@code false} otherwise.     */    public synchronized boolean removeElement(Object obj) {        modCount++;        int i = indexOf(obj);        if (i >= 0) {            removeElementAt(i);            return true;        }        return false;    }    /**     * Removes all components from this vector and sets its size to zero.     *     * <p>This method is identical in functionality to the {@link #clear}     * method (which is part of the {@link List} interface).     */    public synchronized void removeAllElements() {        modCount++;        // Let gc do its work        for (int i = 0; i < elementCount; i++)            elementData[i] = null;        elementCount = 0;    }    /**     * Returns a clone of this vector. The copy will contain a     * reference to a clone of the internal data array, not a reference     * to the original internal data array of this {@code Vector} object.     *     * @return  a clone of this vector     */    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);        }    }    /**     * Returns an array containing all of the elements in this Vector     * in the correct order.     *     * @since 1.2     */    public synchronized Object[] toArray() {        return Arrays.copyOf(elementData, elementCount);    }    /**     * Returns an array containing all of the elements in this Vector in the     * correct order; the runtime type of the returned array is that of the     * specified array.  If the Vector fits in the specified array, it is     * returned therein.  Otherwise, a new array is allocated with the runtime     * type of the specified array and the size of this Vector.     *     * <p>If the Vector fits in the specified array with room to spare     * (i.e., the array has more elements than the Vector),     * the element in the array immediately following the end of the     * Vector is set to null.  (This is useful in determining the length     * of the Vector <em>only</em> if the caller knows that the Vector     * does not contain any null elements.)     *     * @param a the array into which the elements of the Vector are to     *          be stored, if it is big enough; otherwise, a new array of the     *          same runtime type is allocated for this purpose.     * @return an array containing the elements of the Vector     * @throws ArrayStoreException if the runtime type of a is not a supertype     * of the runtime type of every element in this Vector     * @throws NullPointerException if the given array is null     * @since 1.2     */    @SuppressWarnings("unchecked")    public synchronized <T> T[] toArray(T[] a) {        if (a.length < elementCount)            return (T[]) Arrays.copyOf(elementData, elementCount, a.getClass());        System.arraycopy(elementData, 0, a, 0, elementCount);        if (a.length > elementCount)            a[elementCount] = null;        return a;    }    // Positional Access Operations    @SuppressWarnings("unchecked")    E elementData(int index) {        return (E) elementData[index];    }    /**     * Returns the element at the specified position in this Vector.     *     * @param index index of the element to return     * @return object at the specified index     * @throws ArrayIndexOutOfBoundsException if the index is out of range     *            ({@code index < 0 || index >= size()})     * @since 1.2     */    public synchronized E get(int index) {        if (index >= elementCount)            throw new ArrayIndexOutOfBoundsException(index);        return elementData(index);    }    /**     * Replaces the element at the specified position in this Vector with the     * specified element.     *     * @param index index of the element to replace     * @param element element to be stored at the specified position     * @return the element previously at the specified position     * @throws ArrayIndexOutOfBoundsException if the index is out of range     *         ({@code index < 0 || index >= size()})     * @since 1.2     */    public synchronized E set(int index, E element) {        if (index >= elementCount)            throw new ArrayIndexOutOfBoundsException(index);        E oldValue = elementData(index);        elementData[index] = element;        return oldValue;    }    /**     * Appends the specified element to the end of this Vector.     *     * @param e element to be appended to this Vector     * @return {@code true} (as specified by {@link Collection#add})     * @since 1.2     */    public synchronized boolean add(E e) {        modCount++;        ensureCapacityHelper(elementCount + 1);        elementData[elementCount++] = e;        return true;    }    /**     * Removes the first occurrence of the specified element in this Vector     * If the Vector does not contain the element, it is unchanged.  More     * formally, removes the element with the lowest index i such that     * {@code (o==null ? get(i)==null : o.equals(get(i)))} (if such     * an element exists).     *     * @param o element to be removed from this Vector, if present     * @return true if the Vector contained the specified element     * @since 1.2     */    public boolean remove(Object o) {        return removeElement(o);    }    /**     * Inserts the specified element at the specified position in this Vector.     * Shifts the element currently at that position (if any) and any     * subsequent elements to the right (adds one to their indices).     *     * @param index index at which the specified element is to be inserted     * @param element element to be inserted     * @throws ArrayIndexOutOfBoundsException if the index is out of range     *         ({@code index < 0 || index > size()})     * @since 1.2     */    public void add(int index, E element) {        insertElementAt(element, index);    }    /**     * Removes the element at the specified position in this Vector.     * Shifts any subsequent elements to the left (subtracts one from their     * indices).  Returns the element that was removed from the Vector.     *     * @throws ArrayIndexOutOfBoundsException if the index is out of range     *         ({@code index < 0 || index >= size()})     * @param index the index of the element to be removed     * @return element that was removed     * @since 1.2     */    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;    }    /**     * Removes all of the elements from this Vector.  The Vector will     * be empty after this call returns (unless it throws an exception).     *     * @since 1.2     */    public void clear() {        removeAllElements();    }    // Bulk Operations    /**     * Returns true if this Vector contains all of the elements in the     * specified Collection.     *     * @param   c a collection whose elements will be tested for containment     *          in this Vector     * @return true if this Vector contains all of the elements in the     *         specified collection     * @throws NullPointerException if the specified collection is null     */    public synchronized boolean containsAll(Collection<?> c) {        return super.containsAll(c);    }    /**     * Appends all of the elements in the specified Collection to the end of     * this Vector, in the order that they are returned by the specified     * Collection's Iterator.  The behavior of this operation is undefined if     * the specified Collection is modified while the operation is in progress.     * (This implies that the behavior of this call is undefined if the     * specified Collection is this Vector, and this Vector is nonempty.)     *     * @param c elements to be inserted into this Vector     * @return {@code true} if this Vector changed as a result of the call     * @throws NullPointerException if the specified collection is null     * @since 1.2     */    public synchronized boolean addAll(Collection<? extends E> c) {        modCount++;        Object[] a = c.toArray();        int numNew = a.length;        ensureCapacityHelper(elementCount + numNew);        System.arraycopy(a, 0, elementData, elementCount, numNew);        elementCount += numNew;        return numNew != 0;    }    /**     * Removes from this Vector all of its elements that are contained in the     * specified Collection.     *     * @param c a collection of elements to be removed from the Vector     * @return true if this Vector changed as a result of the call     * @throws ClassCastException if the types of one or more elements     *         in this vector are incompatible with the specified     *         collection     * (<a href="Collection.html#optional-restrictions">optional</a>)     * @throws NullPointerException if this vector contains one or more null     *         elements and the specified collection does not support null     *         elements     * (<a href="Collection.html#optional-restrictions">optional</a>),     *         or if the specified collection is null     * @since 1.2     */    public synchronized boolean removeAll(Collection<?> c) {        return super.removeAll(c);    }    /**     * Retains only the elements in this Vector that are contained in the     * specified Collection.  In other words, removes from this Vector all     * of its elements that are not contained in the specified Collection.     *     * @param c a collection of elements to be retained in this Vector     *          (all other elements are removed)     * @return true if this Vector changed as a result of the call     * @throws ClassCastException if the types of one or more elements     *         in this vector are incompatible with the specified     *         collection     * (<a href="Collection.html#optional-restrictions">optional</a>)     * @throws NullPointerException if this vector contains one or more null     *         elements and the specified collection does not support null     *         elements     *         (<a href="Collection.html#optional-restrictions">optional</a>),     *         or if the specified collection is null     * @since 1.2     */    public synchronized boolean retainAll(Collection<?> c) {        return super.retainAll(c);    }    /**     * Inserts all of the elements in the specified Collection into this     * Vector at the specified position.  Shifts the element currently at     * that position (if any) and any subsequent elements to the right     * (increases their indices).  The new elements will appear in the Vector     * in the order that they are returned by the specified Collection's     * iterator.     *     * @param index index at which to insert the first element from the     *              specified collection     * @param c elements to be inserted into this Vector     * @return {@code true} if this Vector changed as a result of the call     * @throws ArrayIndexOutOfBoundsException if the index is out of range     *         ({@code index < 0 || index > size()})     * @throws NullPointerException if the specified collection is null     * @since 1.2     */    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;    }    /**     * Compares the specified Object with this Vector for equality.  Returns     * true if and only if the specified Object is also a List, both Lists     * have the same size, and all corresponding pairs of elements in the two     * Lists are <em>equal</em>.  (Two elements {@code e1} and     * {@code e2} are <em>equal</em> if {@code (e1==null ? e2==null :     * e1.equals(e2))}.)  In other words, two Lists are defined to be     * equal if they contain the same elements in the same order.     *     * @param o the Object to be compared for equality with this Vector     * @return true if the specified Object is equal to this Vector     */    public synchronized boolean equals(Object o) {        return super.equals(o);    }    /**     * Returns the hash code value for this Vector.     */    public synchronized int hashCode() {        return super.hashCode();    }    /**     * Returns a string representation of this Vector, containing     * the String representation of each element.     */    public synchronized String toString() {        return super.toString();    }    /**     * Returns a view of the portion of this List between fromIndex,     * inclusive, and toIndex, exclusive.  (If fromIndex and toIndex are     * equal, the returned List is empty.)  The returned List is backed by this     * List, so changes in the returned List are reflected in this List, and     * vice-versa.  The returned List supports all of the optional List     * operations supported by this List.     *     * <p>This method eliminates the need for explicit range operations (of     * the sort that commonly exist for arrays).  Any operation that expects     * a List can be used as a range operation by operating on a subList view     * instead of a whole List.  For example, the following idiom     * removes a range of elements from a List:     * <pre>     *      list.subList(from, to).clear();     * </pre>     * Similar idioms may be constructed for indexOf and lastIndexOf,     * and all of the algorithms in the Collections class can be applied to     * a subList.     *     * <p>The semantics of the List returned by this method become undefined if     * the backing list (i.e., this List) is <i>structurally modified</i> in     * any way other than via the returned List.  (Structural modifications are     * those that change the size of the List, or otherwise perturb it in such     * a fashion that iterations in progress may yield incorrect results.)     *     * @param fromIndex low endpoint (inclusive) of the subList     * @param toIndex high endpoint (exclusive) of the subList     * @return a view of the specified range within this List     * @throws IndexOutOfBoundsException if an endpoint index value is out of range     *         {@code (fromIndex < 0 || toIndex > size)}     * @throws IllegalArgumentException if the endpoint indices are out of order     *         {@code (fromIndex > toIndex)}     */    public synchronized List<E> subList(int fromIndex, int toIndex) {        return Collections.synchronizedList(super.subList(fromIndex, toIndex),                                            this);    }    /**     * Removes from this list all of the elements whose index is between     * {@code fromIndex}, inclusive, and {@code toIndex}, exclusive.     * Shifts any succeeding elements to the left (reduces their index).     * This call shortens the list by {@code (toIndex - fromIndex)} elements.     * (If {@code toIndex==fromIndex}, this operation has no effect.)     */    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;    }    /**     * Save the state of the {@code Vector} instance to a stream (that     * is, serialize it).     * This method performs synchronization to ensure the consistency     * of the serialized data.     */    private void writeObject(java.io.ObjectOutputStream s)            throws java.io.IOException {        final java.io.ObjectOutputStream.PutField fields = s.putFields();        final Object[] data;        synchronized (this) {            fields.put("capacityIncrement", capacityIncrement);            fields.put("elementCount", elementCount);            data = elementData.clone();        }        fields.put("elementData", data);        s.writeFields();    }    /**     * Returns a list iterator over the elements in this list (in proper     * sequence), starting at the specified position in the list.     * The specified index indicates the first element that would be     * returned by an initial call to {@link ListIterator#next next}.     * An initial call to {@link ListIterator#previous previous} would     * return the element with the specified index minus one.     *     * <p>The returned list iterator is <a href="#fail-fast"><i>fail-fast</i></a>.     *     * @throws IndexOutOfBoundsException {@inheritDoc}     */    public synchronized ListIterator<E> listIterator(int index) {        if (index < 0 || index > elementCount)            throw new IndexOutOfBoundsException("Index: "+index);        return new ListItr(index);    }    /**     * Returns a list iterator over the elements in this list (in proper     * sequence).     *     * <p>The returned list iterator is <a href="#fail-fast"><i>fail-fast</i></a>.     *     * @see #listIterator(int)     */    public synchronized ListIterator<E> listIterator() {        return new ListItr(0);    }    /**     * Returns an iterator over the elements in this list in proper sequence.     *     * <p>The returned iterator is <a href="#fail-fast"><i>fail-fast</i></a>.     *     * @return an iterator over the elements in this list in proper sequence     */    public synchronized Iterator<E> iterator() {        return new Itr();    }    /**     * An optimized version of AbstractList.Itr     */    private class Itr implements Iterator<E> {        int cursor;       // index of next element to return        int lastRet = -1; // index of last element returned; -1 if no such        int expectedModCount = modCount;        public boolean hasNext() {            // Racy but within spec, since modifications are checked            // within or after synchronization in next/previous            return cursor != elementCount;        }        public E next() {            synchronized (Vector.this) {                checkForComodification();                int i = cursor;                if (i >= elementCount)                    throw new NoSuchElementException();                cursor = i + 1;                return elementData(lastRet = i);            }        }        public void remove() {            if (lastRet == -1)                throw new IllegalStateException();            synchronized (Vector.this) {                checkForComodification();                Vector.this.remove(lastRet);                expectedModCount = modCount;            }            cursor = lastRet;            lastRet = -1;        }        @Override        public void forEachRemaining(Consumer<? super E> action) {            Objects.requireNonNull(action);            synchronized (Vector.this) {                final int size = elementCount;                int i = cursor;                if (i >= size) {                    return;                }        @SuppressWarnings("unchecked")                final E[] elementData = (E[]) Vector.this.elementData;                if (i >= elementData.length) {                    throw new ConcurrentModificationException();                }                while (i != size && modCount == expectedModCount) {                    action.accept(elementData[i++]);                }                // update once at end of iteration to reduce heap write traffic                cursor = i;                lastRet = i - 1;                checkForComodification();            }        }        final void checkForComodification() {            if (modCount != expectedModCount)                throw new ConcurrentModificationException();        }    }    /**     * An optimized version of AbstractList.ListItr     */    final class ListItr extends Itr implements ListIterator<E> {        ListItr(int index) {            super();            cursor = index;        }        public boolean hasPrevious() {            return cursor != 0;        }        public int nextIndex() {            return cursor;        }        public int previousIndex() {            return cursor - 1;        }        public E previous() {            synchronized (Vector.this) {                checkForComodification();                int i = cursor - 1;                if (i < 0)                    throw new NoSuchElementException();                cursor = i;                return elementData(lastRet = i);            }        }        public void set(E e) {            if (lastRet == -1)                throw new IllegalStateException();            synchronized (Vector.this) {                checkForComodification();                Vector.this.set(lastRet, e);            }        }        public void add(E e) {            int i = cursor;            synchronized (Vector.this) {                checkForComodification();                Vector.this.add(i, e);                expectedModCount = modCount;            }            cursor = i + 1;            lastRet = -1;        }    }    @Override    public synchronized void forEach(Consumer<? super E> action) {        Objects.requireNonNull(action);        final int expectedModCount = modCount;        @SuppressWarnings("unchecked")        final E[] elementData = (E[]) this.elementData;        final int elementCount = this.elementCount;        for (int i=0; modCount == expectedModCount && i < elementCount; i++) {            action.accept(elementData[i]);        }        if (modCount != expectedModCount) {            throw new ConcurrentModificationException();        }    }    @Override    @SuppressWarnings("unchecked")    public synchronized boolean removeIf(Predicate<? super E> filter) {        Objects.requireNonNull(filter);        // figure out which elements are to be removed        // any exception thrown from the filter predicate at this stage        // will leave the collection unmodified        int removeCount = 0;        final int size = elementCount;        final BitSet removeSet = new BitSet(size);        final int expectedModCount = modCount;        for (int i=0; modCount == expectedModCount && i < size; i++) {            @SuppressWarnings("unchecked")            final E element = (E) elementData[i];            if (filter.test(element)) {                removeSet.set(i);                removeCount++;            }        }        if (modCount != expectedModCount) {            throw new ConcurrentModificationException();        }        // shift surviving elements left over the spaces left by removed elements        final boolean anyToRemove = removeCount > 0;        if (anyToRemove) {            final int newSize = size - removeCount;            for (int i=0, j=0; (i < size) && (j < newSize); i++, j++) {                i = removeSet.nextClearBit(i);                elementData[j] = elementData[i];            }            for (int k=newSize; k < size; k++) {                elementData[k] = null;  // Let gc do its work            }            elementCount = newSize;            if (modCount != expectedModCount) {                throw new ConcurrentModificationException();            }            modCount++;        }        return anyToRemove;    }    @Override    @SuppressWarnings("unchecked")    public synchronized void replaceAll(UnaryOperator<E> operator) {        Objects.requireNonNull(operator);        final int expectedModCount = modCount;        final int size = elementCount;        for (int i=0; modCount == expectedModCount && i < size; i++) {            elementData[i] = operator.apply((E) elementData[i]);        }        if (modCount != expectedModCount) {            throw new ConcurrentModificationException();        }        modCount++;    }    @SuppressWarnings("unchecked")    @Override    public synchronized void sort(Comparator<? super E> c) {        final int expectedModCount = modCount;        Arrays.sort((E[]) elementData, 0, elementCount, c);        if (modCount != expectedModCount) {            throw new ConcurrentModificationException();        }        modCount++;    }    /**     * Creates a <em><a href="Spliterator.html#binding">late-binding</a></em>     * and <em>fail-fast</em> {@link Spliterator} over the elements in this     * list.     *     * <p>The {@code Spliterator} reports {@link Spliterator#SIZED},     * {@link Spliterator#SUBSIZED}, and {@link Spliterator#ORDERED}.     * Overriding implementations should document the reporting of additional     * characteristic values.     *     * @return a {@code Spliterator} over the elements in this list     * @since 1.8     */    @Override    public Spliterator<E> spliterator() {        return new VectorSpliterator<>(this, null, 0, -1, 0);    }    /** Similar to ArrayList Spliterator */    static final class VectorSpliterator<E> implements Spliterator<E> {        private final Vector<E> list;        private Object[] array;        private int index; // current index, modified on advance/split        private int fence; // -1 until used; then one past last index        private int expectedModCount; // initialized when fence set        /** Create new spliterator covering the given  range */        VectorSpliterator(Vector<E> list, Object[] array, int origin, int fence,                          int expectedModCount) {            this.list = list;            this.array = array;            this.index = origin;            this.fence = fence;            this.expectedModCount = expectedModCount;        }        private int getFence() { // initialize on first use            int hi;            if ((hi = fence) < 0) {                synchronized(list) {                    array = list.elementData;                    expectedModCount = list.modCount;                    hi = fence = list.elementCount;                }            }            return hi;        }        public Spliterator<E> trySplit() {            int hi = getFence(), lo = index, mid = (lo + hi) >>> 1;            return (lo >= mid) ? null :                new VectorSpliterator<E>(list, array, lo, index = mid,                                         expectedModCount);        }        @SuppressWarnings("unchecked")        public boolean tryAdvance(Consumer<? super E> action) {            int i;            if (action == null)                throw new NullPointerException();            if (getFence() > (i = index)) {                index = i + 1;                action.accept((E)array[i]);                if (list.modCount != expectedModCount)                    throw new ConcurrentModificationException();                return true;            }            return false;        }        @SuppressWarnings("unchecked")        public void forEachRemaining(Consumer<? super E> action) {            int i, hi; // hoist accesses and checks from loop            Vector<E> lst; Object[] a;            if (action == null)                throw new NullPointerException();            if ((lst = list) != null) {                if ((hi = fence) < 0) {                    synchronized(lst) {                        expectedModCount = lst.modCount;                        a = array = lst.elementData;                        hi = fence = lst.elementCount;                    }                }                else                    a = array;                if (a != null && (i = index) >= 0 && (index = hi) <= a.length) {                    while (i < hi)                        action.accept((E) a[i++]);                    if (lst.modCount == expectedModCount)                        return;                }            }            throw new ConcurrentModificationException();        }        public long estimateSize() {            return (long) (getFence() - index);        }        public int characteristics() {            return Spliterator.ORDERED | Spliterator.SIZED | Spliterator.SUBSIZED;        }    }}



0 0
原创粉丝点击