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

一、继承关系

public class Vector extends AbstractList implements List, 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


(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是否小于0
	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;
    }


(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 v = (Vector) 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[] 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 {
        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 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 {
         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 implements Spliterator

五、Iterator和Enumeration比较

在Java集合中,我们通常都通过 “Iterator(迭代器)” 或 “Enumeration(枚举类)” 去遍历集合。今天,我们就一起学习一下它们之间到底有什么区别。
我们先看看 Enumeration.java 和 Iterator.java的源码,再说它们的区别。
Enumeration是一个接口,它的源码如下:
package java.util;

public interface Enumeration {

    boolean hasMoreElements();

    E nextElement();
}
Iterator也是一个接口,它的源码如下:
package java.util;

public interface Iterator {
    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快。







你可能感兴趣的:(java集合类源码笔记)