初识ArrayList源代码

目录

1.成员变量

2.add方法

    2.1:扩容的代码

    总结一下就是(jdk8)

    2.2:将元素放到集合数组末尾中

3:remove方法


1.成员变量

  //元素数组

    Object[] elementData

  //The size of the ArrayList (the number of elements it contains),就是集合中包含元素的数量
     
    int size 

 //集合结构被修改的次数,其实就是集合新增,删除操作这个字段都会增加1.在调用迭代器操作时,则会检查这个值,如果发现已更改,抛出异常
    int modCount = 0

如果我们创建集合的时候没有指定初始化大小,就会调用下面这个构造方法,如果我们只是创建集合,那么集合的数组长度就是0

public ArrayList() {
        this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
    }

    如果创建集合,然后add一个数据,那么集合的数组长度就会设置成默认的长度,也就是10

2.add方法

    我就看了我们常用的,就直接在集合末尾加入一个元素,他还有在某个索引位子加入一个元素的add方法.

public boolean add(E e) {
        ensureCapacityInternal(size + 1);  // Increments modCount!! 扩容
        elementData[size++] = e; //给数组末尾新增一个数据
        return true;
    }

    2.1:扩容的代码

private void grow(int minCapacity) {
        // overflow-conscious code
        //minCapacity是我们创建集合设置的大小+1和默认集合大小10中最大的数值
        int oldCapacity = elementData.length;
        //新的容量是集合中数组长度的1.5倍
        int newCapacity = oldCapacity + (oldCapacity >> 1);
        //如果新的容量小于minCapacity就设置新的容量=minCapacity,也就是要选择minCapacity和集合长度1.5倍中最大的那个.
        if (newCapacity - minCapacity < 0)
            newCapacity = minCapacity;
        //如果新的容量大于Integer最大-8也就是(2147483639)
        if (newCapacity - MAX_ARRAY_SIZE > 0)
            newCapacity = hugeCapacity(minCapacity);
        // 不然就设置数据长度=新的容量,开始的时候因为数组长度是0,然后加1等于1小于10,所以新的容量就是10,
//这也就是为什么创建集合没有设置集合大小,第一次新增的时候设置集合大小是10的原因.
        elementData = Arrays.copyOf(elementData, newCapacity);
    }




//如果默认大小和我们集合中数组长度+1中最大的那个比2147483639还要大,那就返回集合大小是Integer的最大值,
//不然就是2147483639(Integer最大-8)

 private static int hugeCapacity(int minCapacity) {
        if (minCapacity < 0) // overflow
            throw new OutOfMemoryError();
        return (minCapacity > MAX_ARRAY_SIZE) ?
            Integer.MAX_VALUE :
            MAX_ARRAY_SIZE;
    }

    总结一下就是(jdk8)

      这里面有一个需要注意的是集合中数组长度length不一定等于集合的大小size,集合中数组长度是指当前集合的数组能够放多少数据,集合的大小size指的是集合当前有多少数据.

     扩容大小 : 如果原集合大小的1.5倍和默认大小10和size+1三个中的最大值是否大于integer的最大值-8

                            否 : 那么创建的就是这三个中最大的那个的大小的数组假设是resultCapacity。

                            是 : 就判断默认大小10和size+1中最大值是否大于integer最大值-8

                                       是 : 就创建integer最大值的数组

                                       否 : 则就是integer最大值-8大小的数组

    

        if(集合中数组长度的1.5倍小于默认大小和集合中size+1中最大的那个 且 集合中数组长度的1.5倍小于Integer最大值-8){
            最终集合大小就是默认大小和集合中size+1中最大的那个;
        }
        if(集合中数组长度的1.5倍小于默认大小和集合中size+1中最大的那个 且 集合中数组长度的1.5倍大于Integer最大值-8){
            if(集合中数组长度的1.5倍大于Integer最大值-8){
                if(默认大小和集合中size+1中最大的那个也大于Integer-8){
                    最终集合大小就是Integer的最大值;
                }else{
                    最终集合大小就是Integer最大值-8;
                }
            }
        }
        if(集合中数组长度的1.5倍大于默认大小和集合中size+1中最大的那个 且 集合中数组长度的1.5倍小于Integer最大值-8){
            最终集合大小就是集合中数组长度的1.5倍;
        }
        if(集合中数组长度的1.5倍大于默认大小和集合中size+1中最大的那个 且 集合中数组长度的1.5倍大于Integer最大值-8){
            if(集合中数组长度的1.5倍大于Integer最大值-8){
                if(默认大小和集合中size+1中最大的那个也大于Integer-8){
                    最终集合大小就是Integer的最大值;
                }else{
                    最终集合大小就是Integer最大值-8;
                }
            }
        }

    2.2:将元素放到集合数组末尾中

 elementData[size++] = e;

3:remove方法

  public E remove(int index) {
//校验索引是否大于集合的大小size
        rangeCheck(index);
//操作数量+1
        modCount++;
//获取到该索引位子的数据
        E oldValue = elementData(index);

        int numMoved = size - index - 1;
        if (numMoved > 0)
//相当于index后面的数据往前挪了一位
            System.arraycopy(elementData, index+1, elementData, index,
                             numMoved);
//将最后一位设置成null,让gc回收
        elementData[--size] = null; // clear to let GC do its work
//返回索引位子的数据
        return oldValue;
    }

System.arraycopy方法的定义

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值