Análisis de código fuente vectorial del código fuente JDK

Este artículo ha participado en el evento "Ceremonia de creación de recién llegados" para comenzar juntos el camino de la creación de oro.

Este artículo se publicó por primera vez en CSDN, por lo que también hay marcas de agua de CSDN en las imágenes. Los artículos son originales y no hay infracción.

Vector es una matriz dinámica, y la capa inferior también es una matriz. Vector es muy similar a ArrayList, pero algunos detalles son diferentes. Por ejemplo, Vector es seguro para subprocesos y la expansión de Vector se duplica de forma predeterminada.

1. Sistema de herencia

inserte la descripción de la imagen aquí

  • Implementa la interfaz List y tiene el marco básico de colecciones, como la adición, eliminación y modificación de colecciones.
  • La interfaz RandomAccess está implementada y tiene las características de acceso aleatorio.De hecho, la capa inferior de Vector es una matriz, que tiene las características de acceso aleatorio.
  • Implementa la interfaz Cloneable y se puede clonar, pero el clon aquí es un clon superficial
  • Implementa la interfaz Serializable y se puede serializar y deserializar

2. Variables miembro

/*
    Vector的成员变量是用protected修饰的,ArrayList的成员变量是用private修饰的,
    用private修饰的变量只能在本类调用
    用protected修饰的成员变量只能在同一个包下调用或是在不同包的子类调用
    */

    //底层数组
    protected Object[] elementData;

    //数组实际存储的元素数量
    protected int elementCount;

    //增长系数,表示每次扩容增加多少的容量,如果为0每次扩容为原来的两倍,大于0则每次数组容量增加这个数
    protected int capacityIncrement;

    private static final long serialVersionUID = -2767605614048989439L;
复制代码

3. Constructor

//无参构造方法,默认初始容量为10
    public Vector() {
                this(10);
            }
    //传入指定容量的构造方法,里面调用指定初始容量和增长系数的方法,增长系数默认为0
    public Vector(int initialCapacity) {
                 this(initialCapacity, 0);
             }
    //传入指定容量和增长系数的构造方法
    public Vector(int initialCapacity, int capacityIncrement) {
            super();
            //指定容量小于0,抛出异常
            if (initialCapacity < 0)
                throw new IllegalArgumentException("Illegal Capacity: "+
                                                   initialCapacity);
            this.elementData = new Object[initialCapacity]; //初始容量
            this.capacityIncrement = capacityIncrement;     //增长系数
        }
    //传入集合的构造方法
    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);
        }
复制代码

4. Métodos de miembro

obtener (índice int)

Obtener los datos en el subíndice especificado

public synchronized E get(int index) {
        if (index >= elementCount)       //索引非法,抛出异常
            throw new ArrayIndexOutOfBoundsException(index);

        return elementData(index);
    }
复制代码
conjunto (índice int, elemento E)

Modificar el elemento de datos en el subíndice especificado

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

        E oldValue = elementData(index);
        elementData[index] = element;
        return oldValue;
    }
复制代码
quitar(Objeto o)

eliminar el elemento de datos especificado

public boolean remove(Object o) {
        return removeElement(o);
    }
public synchronized boolean removeElement(Object obj) {
        modCount++;      //集合底层修改次数
        int i = indexOf(obj);      //找到要删除数据元素的下标
        if (i >= 0) {
            removeElementAt(i);    //根据下标删除元素
            return true;           //删除成功
        }
        return false;
    }

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 */    //末尾置空
    }
//删除指定索引处的元素
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);					//copy
        elementData[--elementCount] = null; // Let gc do its work		//数组末尾值空

        return oldValue;			//返回删除指定索引前该索引处的元素
    }
复制代码
añadir (E y)

agregar un elemento al final de la colección

public synchronized boolean add(E e) {
        modCount++;          //集合底层修改次数加1
        ensureCapacityHelper(elementCount + 1);  //判断是否需要扩容
        elementData[elementCount++] = e;
        return true;
    }
复制代码

5. Otros métodos

//拷贝方法,将集合底层数组的全部元素copy到anArray数组中去
public synchronized void copyInto(Object[] anArray) {
        System.arraycopy(elementData, 0, anArray, 0, elementCount);
    }

//将底层数组的容量改为实际存储的元素个数
public synchronized void trimToSize() {
        modCount++;          //集合底层修改次数
        int oldCapacity = elementData.length;    //容量大小
        if (elementCount < oldCapacity) {        //说明实际存储的元素数量小于集合的容量
             //将elementData数组的前elementCount个元素以数组的形式中并返回
            elementData = Arrays.copyOf(elementData, elementCount);
        }
    }

//设置底层数组的容量大小
public synchronized void setSize(int newSize) {
        modCount++;          //底层数组修改次数
        if (newSize > elementCount) {    //新的容量大于数组中实际存储的元素数量
            ensureCapacityHelper(newSize);   //判断是否需要扩容
        } else {
            for (int i = newSize ; i < elementCount ; i++) { //新的容量小于数组实际存储的元素数量,一定不扩容,多出的元素置为null
                elementData[i] = null;
            }
        }
        elementCount = newSize;      //底层数组实际存储的元素数量
    }

//获取底层数组的容量
public synchronized int capacity() {
        return elementData.length;
    }
//获取底层数组实际存储的元素数量
public synchronized int size() {
        return elementCount;
    }
//判断集合中是否含有元素o
public boolean contains(Object o) {
        return indexOf(o, 0) >= 0;       //从下标0开始寻找第一次出现元素o的位置
    }

//返回元素o第一次出现位置的下标
public int indexOf(Object o) {
        return indexOf(o, 0);
    }

//获取集合中从下标index开始第一次出现元素o的下标
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;                   //未找到返回-1
    }
复制代码

6. Mecanismo de expansión

//确保容量
//加有锁,保证是安全的
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);
    }
private void grow(int minCapacity) {
        // overflow-conscious code
        int oldCapacity = elementData.length;       //旧数组的容量
         //增长系数为0,则容量扩大为原来的2倍;否则扩大增长系数个容量
        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);  //copy方法
    }

private static int hugeCapacity(int minCapacity) {
        if (minCapacity < 0) // overflow                //最小容量小于0,抛出异常
            throw new OutOfMemoryError();
        return (minCapacity > MAX_ARRAY_SIZE) ?         //最小容量大于数组最大长度,容量置为整型的最大值,否则容量置为最大数组长度
            Integer.MAX_VALUE :
            MAX_ARRAY_SIZE;
    }
复制代码

7. Resumen

  • La capa inferior de Vector es una matriz. Cuando usamos el método sin parámetros para construir, la capacidad predeterminada es 10

  • La expansión de Vector está relacionada con el coeficiente de crecimiento. Si el coeficiente de crecimiento es 0, la capacidad de la matriz se duplicará cada vez que se expanda. De lo contrario, el tamaño del coeficiente de crecimiento de dígitos aumentará según la capacidad de la matriz.

  • Muchos métodos de Vector están sincronizados, lo que indica que son seguros para subprocesos

  • Muchos métodos de Vector son los mismos que ArrayList, por lo que aquí solo se presentan algunos métodos. Para obtener más información, consulte el análisis del código fuente de ArrayList.

Supongo que te gusta

Origin juejin.im/post/7084005297106190343
Recomendado
Clasificación