ArrayList的深入理解

文章详细解析了ArrayList的无参构造器,add方法及其扩容机制,get和remove方法的工作原理,以及modCount在防止并发修改中的作用。还提供了手写一个简单List实现的示例,强调了动态扩容和存储删除的关键步骤。
摘要由CSDN通过智能技术生成

1. 实例化无参构造器

  • Arraylist作为日常最一个类,内部是动态扩容数组,与普通数组的区别就是它是没有固定大小的限制,并且是线程不安全的
  • 先看实例化的无参构造器
    在这里插入图片描述
  • 执行实例化是要调用其无参构造方法,无参构造方法就是给elementData初始化分配地址值,也就是实例化一下,不初始化的默认值为null
    在这里插入图片描述
 transient Object[] elementData; // non-private to simplify nested class access
 
 private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};

2. add()方法

在这里插入图片描述

  • 在认识一下源码中的Size,也就是数组的长度大小
  • 源码中的DEFAULT_CAPACITY 也就是数组的默认值的大小
    在这里插入图片描述

在这里插入图片描述

  • size默认的初始化是0,调用的是ensureCapacityInternal()传递的是长度+1的数值
    在这里插入图片描述
    在这里插入图片描述
  • 看一下方法,传递的参数是elementData,也就是list存储元素的数组和minCapacity,也就是长度+1数组的长度
  • 这个判断是判断地址值是否相等,相等的话,在(默认值10,和传递的minCapacity 是数字的默认值+1),现在是返回的是10,因为10大
    在这里插入图片描述
  • modCount++; 这个操作,最后在说
  • minCapacity是刚才调用的calculateCapacity方法返回的默认值和传递的大小中的最大值,目前是10
  • 判断:如果10(默认长度)-elementData.length(默认值0)>0,这个就是ArrayList中核心的一个数组扩容的方法,超过了数组的容量限制执行扩容方法
    在这里插入图片描述
    grow方法
    oldCapacity 是数组原来的长度,现在是0
    newCapacity是数组新的长度,用老数组位移得到
    如果新数组长度-minCapacity(10初始化)=0,新的数组长度就是默认值10初始化默认值10
    最后就是拷贝一份,将原elementData拷贝出来一份默认值为10的数组
    在这里插入图片描述
  • 致此,这个阶段就完成了,第一次add的ensureCapacityInternal方法的作用是初始化了一个长度为10的数组
  • 然后将元素添加到数组之中返回true
    在这里插入图片描述

2.1. add()List的扩容

  • List的扩容机制体现在这里 ,第一次初始化需要扩容数组长度是10
  • 然后以后每次扩容依靠的是,是够超过了数组的容量,然后进行扩容,扩容执行的是grow方法,非扩容直接添加
    在这里插入图片描述
    在这里插入图片描述
  • 扩容扩原数组的1.5倍大小,然后copy一个新的数组,进行返回
    在这里插入图片描述

3. get()方法

  • get方法就是,传递的index超过了数组的长度就抛异常
  • return elementData(index);
    在这里插入图片描述

4. remove()

  • remove方法其实就是一个拷贝的过程
第一个参数默认是src 来源数组 类型为数组
第二个参数默认是srcPos 从来源数组开始复制的位置 类型为整行(其实就是下标)
第三个参数默认是dest 目标数组 类型为数组
第四个参数默认是destPos 目标数组接收起始位置类型为整行(其实就是下标)
第五个参数默认是length 复制的长度

在这里插入图片描述

5. modCount++ 的作用(面试题)

  • 通过看源码发现add和删除等一些地方有modCount++这个代码,这个代码的作用是,在遍历中,为了避免一边修改数据,一边拿数据,进而造成的数据混乱
 public void remove() {
            if (lastRet < 0)
                throw new IllegalStateException();
            checkForComodification();
 
            try {
                ArrayList.this.remove(lastRet);
                cursor = lastRet;
                lastRet = -1;
                expectedModCount = modCount;
            } catch (IndexOutOfBoundsException ex) {
                throw new ConcurrentModificationException();
            }
        }

5. 手写简单List实现存储删除

package com.rj.bd.Test;

import lombok.Data;

import java.util.Arrays;

/**
 * @author LXY
 * @desc
 * @time 2023--04--10--10:46
 */
public class YList<T> {
    //初始化
    private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
    //数组初始化默认大小
    private  static  final  int DEFAULT_CAPACITY =10;

    Object[] elementData;
    //初始化0
    private  int Size;

    //添加方法
    public  void add(T e){
        ensureCapacityInternal(Size+1);
        elementData[Size++]=e;
    }


    public void  remove(int index) {
        int numMoved = Size - index - 1;
        if (numMoved > 0)
            System.arraycopy(elementData, index+1, elementData, index,
                    numMoved);
        elementData[--Size] = null; // clear to let GC do its work
    }



    //添加方法
    public  T get(int index){
        if (elementData.length-index<0){
            try {
                throw  new Exception("数组越界");
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return (T) elementData[index];
    }


    //判断最大值
    private int ensureCapacityMax(int minsize){
        return Math.max(minsize, Size);
    }

    private void ensureCapacityInternal(int minsize) {
        int indexs = ensureCapacityMax(minsize);

        if (indexs>elementData.length){
            grep(indexs);
        }
    }

    //扩容方法
    private void grep(int minCapacity) {
        //原来的长度
        int oldCapacity=elementData.length;
        int newCapacity= oldCapacity + (oldCapacity >> 1);

        if (newCapacity-minCapacity<0){
            newCapacity=DEFAULT_CAPACITY;
        }
        elementData = Arrays.copyOf(elementData, newCapacity);
    }


    //无参构造器,初始化
    public  YList (){
        elementData=DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
    }



}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值