ArrayList和Vector的扩容机制

ArrayList
底层是一个对象数组:protected Object[]elementData;
无参构造:
ArrayList先通过无参构造器被赋予一个空的数组elementData,初始容量为0
添加元素时执行list.add
list.add中
1)先调用ensureCapacitynternal方法确定是否扩容并且向该方法传入size+1参数
ensureCapacitynternal方法用minCapacity接受了size+1参数作为此时数组需要的最小容量
先判断数组是否为空,如果为空则将一个默认初值DEFAULT_CAPACITY=10和minCapacity中的最大值赋给minCapacity,第一次赋值当然10大所以第一次minCapacity变成10
然后ensureCapacitynternal方法中调用了ensureExplicitCapacity方法
其中modCount++记录集合被修改次数(避免多线程操作异常)
再比较minCapacity和数组大小elementData数组长度,如果前者大于后者就就进行真正的扩容(通过grow方法)
grow方法才是真的扩容,先将原来数组长度elementData.length赋给一个变量oldCapacity
再将一个变量newCapacity被赋予oldCapacity的1.5倍,因为第一次oldCapacity=0,所以1.5倍之后还是0所以newCapacity=0
再比较newCapacity和minCapacity比较如果前者大的话就调用Arrays.copyOf(底层其实是System.copyOf)第一次newCapacity=0所以小于minCapacity=10所以第一次扩容将minCapacity赋给newCapacity
elementData = Arrays.copyOf(elementData , newCapacity);
将ArrayList维护的elementData数组容量扩大到1.5倍
然后逐步返回,最后返回到add方法
2)执行赋值elementData[size++]=e;
将要添加的变量e添加到扩容后的数组下标为size的位置中,然后下标+1

有参构造:
ArrayList有参构造器的initialCapacity形参接受用户指定的的数组初始大小
并创建一个容量为initialCapacity大小的空数组
this.elementData = new Object[initialCapacity]
剩下的流程和无参构造一样


Vector
底层也是一个对象数组 protected Object[]elementData;
Vector是线程安全的,操作方法带有synchronized修饰
流程大致和ArrayList一致
其中ArrayList中的ensurCapacityInternal方法被替换成了ensureCapacityHelper

其中最需要关注的的是Vector的grow扩容机制
先看Vector的构造器
其中capacityincrement是Vector的扩容因子

无参构造器:数组初始容量initialcapacity默认为10
public Vector() {
    this(initialcapacity:10);
}
单个参数构造器:传入一个初始数组容量
public Vector(int initialCapacity) {
    this(initialCapacity, 0);
}
双参数构造器:传入一个数组初始容量和一个扩容因子

public Vector(int initialCapacity, int capacityIncrement) {
    super();
    if (initialCapacity < 0)
        throw new IllegalArgumentException("Illegal Capacity: "+
                                           initialCapacity);
    this.elementData = new Object[initialCapacity];
    this.capacityIncrement = capacityIncrement;
}

再看Vector的grow扩容机制
private Object[] grow(int minCapacity) {
    int oldCapacity = elementData.length;
    int newCapacity = ArraysSupport.newLength(oldCapacity,
            minCapacity - oldCapacity, /* minimum growth */
            capacityIncrement > 0 ? capacityIncrement : oldCapacity
                                       /* preferred growth */);
    return elementData = Arrays.copyOf(elementData, newCapacity);
}

private Object[] grow() {
    return grow(elementCount + 1);
}

扩容时候先调用下面的grow再调用上面的grow通过minCapacity接受elementCount+1即所需最小的数组容量
其他和ArrayList差不多关键是下面的
capacityIncrement > 0 ? capacityIncrement : oldCapacity
                           /* preferred growth */);
如果扩容因子为0的话就按照两倍扩容有参的就是参数的两倍,无参的就是10的两倍
有扩容因子的话就按照扩容因子大小扩容

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值