JAVA 集合类(java.util)源码阅读笔记------Vector

来源:互联网 发布:网络侵权司法解释全文 编辑:程序博客网 时间:2024/06/05 01:52

一、继承关系

public class Vector<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, java.io.Serializable
(1)继承自AbstractList类
(2)List接口:继承自Collection接口,同时自己也定义了一系列索引访问功能。
(3)RandomAccess:空接口,实现该接口代表该类拥有随机访问list对象的能力。
(4)Cloneable:空接口,实现该接口,重写Object的clone方法,否则会抛出异常。调用super.clone()实现对象的复制,如果对象中有引用,可以在super.clone后面进行处理。
(5)java.io.Serializable:空接口,实现该接口代表该类可序列化


二、成员变量

protected Object[] elementData;//内部还是采用一个数组保存list中的元素protected int elementCount;//数组实际包含的元素的个数protected int capacityIncrement;//每次增长的大小(不是增长率),当值小于等于0时,容量每次增长的容量为elementData.length(即倍增原数组的大小)private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8; //数组的最大容量

三、方法说明

(1)构造方法,如果不提供初始容量,则默认数组大小为10

public Vector() {        this(10);    }


(2)同步方法:trimToSize,将数组的容量修改成实际容量的大小,即令elementData.length=elementCount

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


(3)同步方法:ensureCapacity,保证数组的最小容量

    public synchronized void ensureCapacity(int minCapacity) {        if (minCapacity > 0) {            modCount++;            ensureCapacityHelper(minCapacity);        }    }//调用了ensureCapacityHelper:    private void ensureCapacityHelper(int minCapacity) {        // overflow-conscious code        if (minCapacity - elementData.length > 0)            grow(minCapacity);    }//调用了grow:    private void grow(int minCapacity) {        // overflow-conscious code        int oldCapacity = elementData.length;//如果capacityIncrement<0,则newCapacity=oldCapacity+oldCapacity;//否则则newCapacity=oldCapacity+capacityIncrement;        int newCapacity = oldCapacity + ((capacityIncrement > 0) ?                                         capacityIncrement : oldCapacity);//如果增长后仍不能保证满足minCapacity,则令newCapacity = minCapacity        if (newCapacity - minCapacity < 0)            newCapacity = minCapacity;//若增长后的大小大于允许的最大长度,则调用hugeCapacity        if (newCapacity - MAX_ARRAY_SIZE > 0)            newCapacity = hugeCapacity(minCapacity);//调用Arrays.copyof方法将elementData拷贝到一个容量为newCapacity的数组中。//Arrays.copyOf(elementData, newCapacity)实际上是通过System.arraycopy(original, 0, copy, 0,Math.min(original.length, newLength));来实现的        elementData = Arrays.copyOf(elementData, newCapacity);    }//调用了hugeCapacity    private static int hugeCapacity(int minCapacity) {        if (minCapacity < 0) // overflow            throw new OutOfMemoryError();//MAX_ARRAY_SIZE=Integer.MAX_VALUE-8        return (minCapacity > MAX_ARRAY_SIZE) ?            Integer.MAX_VALUE :            MAX_ARRAY_SIZE;    }


(4)同步方法:setSize,将elementData.length设置为newSize

    public synchronized void setSize(int newSize) {        modCount++;        if (newSize > elementCount) {//若newSize<elementData.length,则不用扩容,否则需要扩容            ensureCapacityHelper(newSize);        } else {//若newSize<elementData的实际大小(elementCount),则将newSize及其后面的数组都置为空            for (int i = newSize ; i < elementCount ; i++) {                elementData[i] = null;            }        }        elementCount = newSize;    }


(5)同步方法:capacity,返回数组的大小;size,返回数组包含的元素的个数;isEmpty,判断数组是否没有元素

    public synchronized int capacity() {        return elementData.length;    }public synchronized int size() {        return elementCount;    }public synchronized boolean isEmpty() {        return elementCount == 0;    }


(6)同步方法:删除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) {//将elementData从index+1到elementCount为止的元素向前移动一个位置,覆盖Index处的元素            System.arraycopy(elementData, index + 1, elementData, index, j);        }        elementCount--;        elementData[elementCount] = null; /* to let gc do its work */    }//remove也是删除,但是没有判断index是否小于0public 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;    }


(7)同步方法:insertElementAt,在index处插入obj。

    public synchronized void insertElementAt(E obj, int index) {        modCount++;        if (index > elementCount) {            throw new ArrayIndexOutOfBoundsException(index                                                     + " > " + elementCount);        }//先保证容量大于elementCount+1        ensureCapacityHelper(elementCount + 1);//将elementData数组中index到elementCount之间的元素向后移动一位,给Index处空出位置        System.arraycopy(elementData, index, elementData, index + 1, elementCount - index);        elementData[index] = obj;        elementCount++;    }


(8)同步方法:clone,重写Object父类中的方法

    public synchronized Object clone() {        try {            @SuppressWarnings("unchecked")                Vector<E> v = (Vector<E>) super.clone();//复制一个Vector对象,然后给该对象中的elementData分配空间和填充元素            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);        }    }


(9)同步方法:toArray

@SuppressWarnings("unchecked")    public synchronized <T> T[] toArray(T[] a) {//如果参数a的size不够,则重新申请一个数组空间,并且复制elementData中内容        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;    }



四、内部类

(1)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();        }    }


(2)双向迭代器: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;        }    }


(3)并行迭代器
static final class VectorSpliterator<E> implements Spliterator<E>

五、Iterator和Enumeration比较

在Java集合中,我们通常都通过 “Iterator(迭代器)” 或 “Enumeration(枚举类)” 去遍历集合。今天,我们就一起学习一下它们之间到底有什么区别。
我们先看看 Enumeration.java 和 Iterator.java的源码,再说它们的区别。
Enumeration是一个接口,它的源码如下:
package java.util;public interface Enumeration<E> {    boolean hasMoreElements();    E nextElement();}
Iterator也是一个接口,它的源码如下:
package java.util;public interface Iterator<E> {    boolean hasNext();    E next();    void remove();}
看完代码了,我们再来说说它们之间的区别。
(01) 函数接口不同
        Enumeration只有2个函数接口。通过Enumeration,我们只能读取集合的数据,而不能对数据进行修改。
        Iterator只有3个函数接口。Iterator除了能读取集合的数据之外,也能数据进行删除操作。
(02) Iterator支持fail-fast机制,而Enumeration不支持。
        Enumeration 是JDK 1.0添加的接口。使用到它的函数包括Vector、Hashtable等类,这些类都是JDK 1.0中加入的,Enumeration存在的目的就是为它们提供遍历接口。Enumeration本身并没有支持同步,而在Vector、Hashtable实现Enumeration时,添加了同步。
        而Iterator 是JDK 1.2才添加的接口,它也是为了HashMap、ArrayList等集合提供遍历接口。Iterator是支持fail-fast机制的:当多个线程对同一个集合的内容进行操作时,就可能会产生fail-fast事件。
Enumeration速度比Iterator快。