ArrayList核心源码笔记

一、ArrayList就是一个类,内部封装了Object[]用于存取数据。

@Test
public void testArrayList(){
    List list = new ArrayList<>();
    for (int i = 0; i < 100000; i++) {
        list.add(i);
        list.get(i);
    }
}

二、ADD方法:

  主体逻辑:当插入一个元素时,先判断一下数组还有没有位置可以插入,如果没有先扩容。然后存放数据。

 

  扩容原理:

1、插入式数组为空,则copy一个长度为10的数组来替换原有数组

2、正常扩容逻辑,如果不够用copy一个长度为原来长度1.5的数组替换

3、当正常扩容到Integer.MAX_VALUE - 8后,又放满了,则触发最后一次扩容,将数组长度扩到Integer.MAX_VALUE

4、扩容的缺点:该扩容机智会不断的让原来的数组游离,会对GC造成一定的压力,所以如果对长度有预估的情况下,最好直接创建指定长度的list对象,如案例中 

new ArrayList<>(100000)比较好

 

ADD源码核心逻辑注释:

public boolean add(E e) {

    ensureCapacityInternal(size + 1);  // Increments modCount!!  //判断数组能不能插入这个元素,如果不能则获取扩容的数组  --1

    elementData[size++] = e; // 将e存到index = size的位置

    return true;

}
 
1、
private void ensureCapacityInternal(int minCapacity) {

    if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {  //如果原数组为空,这时minCapacity肯定为1,则将minCapacity赋值为10

        minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
    }



   ensureExplicitCapacity(minCapacity);   --2

}
 
2、
private void ensureExplicitCapacity(int minCapacity) {

    modCount++;  //是扩容的次数

    // overflow-conscious code

    if (minCapacity - elementData.length > 0) //如果放不下,则扩容:用最低需求的容量-数组长度

        grow(minCapacity);  --3
}
 
3、
private void grow(int minCapacity) {

    // overflow-conscious code

    int oldCapacity = elementData.length;

    int newCapacity = oldCapacity + (oldCapacity >> 1); //扩容一般规则:新长度 = 1.5倍的老长度,不含小数。10到15到22到33到49......

    if (newCapacity - minCapacity < 0)  //空数组扩容

        newCapacity = minCapacity;

    if (newCapacity - MAX_ARRAY_SIZE > 0) //数组最后一次扩容触发条件Integer.MAX_VALUE - 8,数组能达到的最大长度还是为Integer.MAX_VALUE

        newCapacity = hugeCapacity(minCapacity);

    // minCapacity is usually close to size, so this is a win:

    elementData = Arrays.copyOf(elementData, newCapacity);

}

三、GET方法:

GET就没啥好说了的,传入的下标和size比较下,越界就抛异常,没越界就拿数据
 

public E get(int index) {
    rangeCheck(index);

    return elementData(index);
}
private void rangeCheck(int index) {
    if (index >= size)
        throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值