ArrayList(一)属性,构造方法分析

  ArrayList是我们常用的集合之一,而我也会陆续对ArrayList集合的源码进行一步步的分析,由于本人的水平有限,难免有些理解上的偏差或错误希望读者能指出。

   1,ArrayList集合中的属性    

   //序列化版本号    
  private static final long serialVersionUID = 8683452581122892189L; //默认初始化长度 private static final int DEFAULT_CAPACITY = 10; //空的elementData数组 private static final Object[] EMPTY_ELEMENTDATA = {}; //默认的初始化空的elementData数组 private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {}; /** * The array buffer into which the elements of the ArrayList are stored. * The capacity of the ArrayList is the length of this array buffer. Any * empty ArrayList with elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA * will be expanded to DEFAULT_CAPACITY when the first element is added. * 存储ArrayList元素的数组缓冲区,ArrayList的容量是此数组缓冲区的长度。任何 * empty ArrayList with elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA * 添加第一个元素时,将扩展为DEFAULT_CAPACITY
   * 主数组 */ transient Object[] elementData; // non-private to simplify nested class access //ArrayList中保存的元素个数 可以当作一个计数器 private int size;
  
   //数组的最大长度
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;

   以上便是ArrayList集合中的主要属性,标红的则是比较重要的属性,接下来我们看看ArrayList的构造方法

     2,ArrayList的构造方法

    1)无参数构造方法      

 //无参数的构造方法
    public ArrayList() {
        //此时 elementData为{}
        this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
    }

    可以看到,当我们调用无参构造方法,创建ArrayList数组时(List list = new ArrayList();),此时ArrayList的底层数组为:{}

    2)带参数构造方法  

 //传入一个初始化参数,对ArrayList数组进行初始化操作
    public ArrayList(int initialCapacity) {
        if (initialCapacity > 0) {//如果传入参数大于0,则ArrayList数组的长度为传入的数值
            this.elementData = new Object[initialCapacity];//此时便已经进行了初始化
        } else if (initialCapacity == 0) {//如果等于零
            this.elementData = EMPTY_ELEMENTDATA;//此时elementData数据为{}
        } else {//小于零抛出异常
            throw new IllegalArgumentException("Illegal Capacity: "+
                                               initialCapacity);
        }
    }

    可以看到,当我们调用有参构造方法创建ArrayList数组时候(List list = new ArrayList(3);),会对我们传入的参数进行判断,如果我们传入的参数大于0则此时对elementData数组进行初始化,初始化的

  数组长度为传入的参数。如果我们传入的参数为0,则将EMPTY_ELEMENTDATA的值赋给elementDate数组为{}。如果传入值小于0,便会抛出相应的参数异常。

    3)传入一个集合作为参数的构造方法

   

  public static void main(String[] args) {
        List list = new ArrayList();
        list.add(null);
        list.add(null);
        list.add("阿里爷爷");
        list.add("阿里爷爷"); list.add("阿里爷爷"); List list2 = new ArrayList(list); System.out.println(list); } 
  //当传入一个集合作为数组初始化参数时
    public ArrayList(Collection<? extends E> c) {
        //将传入的集合转换为一个Object类型的数组,并将此数组的引用赋给elementData
        elementData = c.toArray();
        if ((size = elementData.length) != 0) {//数组不为空的情况
            // c.toArray might (incorrectly) not return Object[] (see 6260652)
            //https://blog.csdn.net/qq_22083043/article/details/77513485
            //Arrays.asList()返回一个内部类,调用内部类的toArray()方法返回的不是一个Object[],而是E[]。
            //elementData.getClass() 一旦不是一个Object[]就会将他复制成为一个Object[]
            if (elementData.getClass() != Object[].class)
                elementData = Arrays.copyOf(elementData, size, Object[].class);
        } else {//数据为空的情况
            // replace with empty array.
            this.elementData = EMPTY_ELEMENTDATA;//elementData为{}
        }
    }

   我们可以看到,首先会通过集合的toArray方法将传入的集合转换为一个数组,然后将数组赋给elementData。然后将elementData.length赋给size,然后对size进行判定是否为0(即elementData数组中书否有元素)如果数组不为空,则会新进行elementData的类型进行判断,判定其是否为Object数组,如果不是便会将elementData数组复制成为一个Object类型的数组。如果为空的情况,则将elementData的数组赋值为{}。

  对应if(elementData.getClass()!=Object[].class),我们可能会不明白,为什么这里需要判断,那么我么需要看看toArray()方法的底层了。

  

  

    可以看到两个copyOf方法使用的都是,Arrays工具类中的copyOf()方法,然后我们查看Arrays的copyOf方法便了然了吧!!

    

    后面笔者会陆续发表关于ArrayList中常用方法的源码解析,以及集合体系中的常用方法,java.util包中的常用方法,总之就是一系列java相关源码。

    最后大家选择这条路,希望你我都能坚持下去。

 

 

 

  

   

    

转载于:https://www.cnblogs.com/liu007/p/10895310.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值