Vector源码分析

一、概述

● 底层原理:是基于数组(Array)的。它使用了可变长度的数组来存储元素,并通过扩容和缩容操作来动态调整数组的大小。
● 特点:
①线程安全
②有序可重复(包含null 值),可通过索引检索
③增加和删除末尾元素的效率较高,但删除中间元素和根据元素值进行查找的效率相对较低。修改元素和根据索引查找元素的操作效率较高
④未指定增量值通常扩容为原容量的2倍
在这里插入图片描述

二、扩容机制

在这里插入图片描述

三、向vector对象中添加元素

boolean add(E e):将指定元素添加到末端

public synchronized boolean add(E e) {
    modCount++;		//计数器自加
    ensureCapacityHelper(elementCount + 1);  	//调用 ensureCapacityHelper 方法来确保 Vector 的容量足够容纳新元素。如果当前容量不足,则会进行扩容操作。
    elementData[elementCount++] = e;		//元素添加
    return true;
}

void add(int index, E element):在指定索引位置添加指定元素

public void add(int index, E element) {
    insertElementAt(element, index);	//用来在指定的 index 索引位置插入元素 element
}

public synchronized void insertElementAt(E obj, int index) {
    modCount++;
    if (index > elementCount) {		//判断索引是否越界
        throw new ArrayIndexOutOfBoundsException(index
                                                 + " > " + elementCount);
    }
    ensureCapacityHelper(elementCount + 1);
    //在指定索引位置处进行元素的后移操作,从而给新元素 obj 腾出空间
    System.arraycopy(elementData, index, elementData, index + 1, elementCount - index);
    elementData[index] = obj;  //在指定索引位置添加元素
    elementCount++;
}

boolean addAll(Collection<? extends E> c) :用于将指定集合c中的所有元素添加到调用该方法的集合中

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);//将数组 a 中的元素复制到 elementData 数组的指定索引位置。
    elementCount += numNew;//更新有效组件的数量,增加新增元素的个数。
    return numNew != 0;
}

boolean addAll(int index, Collection<? extends E> c):用于将指定集合 c 中的所有元素插入到调用该方法的列表中的指定索引位置。

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;	//计算要后移的元素个数,即从索引 index 开始到末尾的元素个数。
    if (numMoved > 0)
        //将需要后移的元素向后移动 numNew 个位置,为插入的新元素腾出空间。
        System.arraycopy(elementData, index, elementData, index + numNew,
                         numMoved);

    System.arraycopy(a, 0, elementData, index, numNew);//将数组 a 中的元素复制到 elementData 数组的指定索引位置。
    elementCount += numNew;//更新有效组件的数量,增加新增元素的个数。
    return numNew != 0;
}
private void ensureCapacityHelper(int minCapacity) {
// overflow-conscious code
//判断当前 Vector 的容量是否小于所需的最小容量。如果当前容量不足以容纳最小容量,则执行扩容操作。
if (minCapacity - elementData.length > 0)
    grow(minCapacity);		//扩容
}


private void grow(int minCapacity) {
    // overflow-conscious code
    int oldCapacity = elementData.length;
    //如果capacityIncrement > 0说明用户指定了增量值,那么新的容量大小为 oldCapacity + capacityIncrement。即使用用户指定的增量来扩充容量。
    // 如果 capacityIncrement <= 0,说明用户没有指定增量值或者增量值为负数,那么新的容量大小为 oldCapacity * 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);
}

在这里插入图片描述

四、移除vector对象中的元素

remove(Object o):移除指定元素

public boolean remove(Object o) {
	return removeElement(o);	//调用 removeElement(o) 方法删除指定对象
}

public synchronized boolean removeElement(Object obj) {
    modCount++;		//计数器自加
    int i = indexOf(obj);	//调用 indexOf(obj) 方法找到对象在列表中的索引
    if (i >= 0) {
        removeElementAt(i); //根据索引移除元素
        return true;
    }
    return false;
}

public int indexOf(Object o) {
    return indexOf(o, 0);	//从索引 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;
}

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; //将最后一个元素修改为null,便于垃圾回收器回收
}

E remove(int index) : 移除指定索引位置的元素

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; //将待删除元素的位置置为 null,以便让垃圾回收器进行处理

    return oldValue;
}

五、修改vector对象中的元素值

E set(int index, E element):修改指定索引位置元素为新元素

public synchronized E set(int index, E element) {
    if (index >= elementCount)	//校验索引是否越界
        throw new ArrayIndexOutOfBoundsException(index);

    E oldValue = elementData(index);	//将旧元素保存到临时变量中
    elementData[index] = element;		//新元素赋值
    return oldValue;
}

void setElementAt(E obj, int index):修改指定索引位置元素

public synchronized void setElementAt(E obj, int index) {
    if (index >= elementCount) {
        throw new ArrayIndexOutOfBoundsException(index + " >= " +
                                                 elementCount);
    }
    elementData[index] = obj;		//将指定索引位置的元素设置为指定的对象。
}

六、查询vector对象中的元素

E get(int index):返回指定索引位置元素的值

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

    return elementData(index);	//调用私有方法 elementData(int index) 来获取指定索引位置的元素值
}

@SuppressWarnings("unchecked")	//该注解禁止编译器产生未经检查的警告,因为类型转换 (E) elementData[index] 可能会引发未经检查的警告
E elementData(int index) {
    return (E) elementData[index];		//返回存储在 elementData 数组指定索引位置的元素,并进行强制类型转换为泛型类型 E
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值