ArrayList详解——逐行分析源码版【还差一丢丢,会尽快补上】

ArrayList详解

初识ArrayList

  1. ArrayList的继承和实现的结构为
ArrayList<E> extends AbstractList<E>
	 implements List<E>, RandomAccess, Cloneable, java.io.Serializable
  1. 抽象类AbstractList中定义了modCount属性,这个参数是指当前列表的结构被修改的次数
    • 结构上的修改指的是那些改变了list的长度大小或者使得遍历过程中产生不正确的结果的其它方式
    • 请留心每一个操作ArrayList中改变存储内容或者改变结构的方法,都会对modCount属性进行++操作
		protected transient int modCount = 0;
		/**
         * The modCount value that the iterator believes that the backing
         * List should have.  If this expectation is violated, the iterator
         * has detected concurrent modification.
         */
        int expectedModCount = modCount;
  1. ArrayList在创建对象的时候并不会初始化容量,当在add或者其他方法调用的时候才会初始化容量【参见精解1】
  2. System.arraycopy复制数组为浅克隆【参见精解2】
  3. System.arraycopy是一个native函数,复制数组时并不是传统意义的——通过数组下标从最后一位依次向后移动一位,而是直接对内存中的数据块进行复制的,是一整块一起复制的,这样效率会大大提升【参见精解2】

成员变量

    //序列化ID
    private static final long serialVersionUID = 8683452581122892189L;

    //ArrayList的默认初始容量大小
    private static final int DEFAULT_CAPACITY = 10;

    //空对象数组,用于空实例的共享空数组实例
    private static final Object[] EMPTY_ELEMENTDATA = {
   };

    //空对象数组,使用无参构造器实例化对象时,将此值赋给elementData
    private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {
   };

    //存放当前数据,ArrayList底层使用的是数组来保存元素
    //ArrayList实现Serializable接口就是允许序列化的,那么为什么该变量却用transient修饰呢?【参见精解3】
    transient Object[] elementData;

    //记录list中存放数据的大小,而不是指数组的length
    //比如 elementData = {"gao","shao",null,null,null}
    //elementData.length 的结果是5;而size保存的数值是2
    private int size;

	//集合所允许的最大容量
    private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;

方法列表

按照定义顺序介绍

public ArrayList(int initialCapacity)

—— 自定义初始化容器大小
	//自定义初始化容器大小
    //当传入的值<0时,抛出异常
    //当传入的值=0时,使用默认大小的数组初始化
    //当传入的值>0时,根据自定义大小初始化容器
    public ArrayList(int initialCapacity) {
   
        if (initialCapacity > 0) {
   
            this.elementData = new Object[initialCapacity];
        } else if (initialCapacity == 0) {
   
            this.elementData = EMPTY_ELEMENTDATA;
        } else {
   
            throw new IllegalArgumentException("Illegal Capacity: "+
                    initialCapacity);
        }
    }

public ArrayList()

—— 无参构造
	//无参构造方法,使用默认大小的数组初始化
    public ArrayList() {
   
        this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
    }

public ArrayList(Collection<? extends E> c)

—— 通过传入集合来初始化当前集合
	//通过传入集合来初始化当前集合
	//将传入的集合中的元素引用复制到当前生成的ArrayList集合中,并且对原先集合中元素的任何修改都会体现到当前集合上【参见精解4】
    public ArrayList(Collection<? extends E> c) {
   
    	//将传入的集合转为Object数组赋值给elementData
        elementData = c.toArray();
        if ((size = elementData.length) != 0) {
   
            //已经通过上面的c.toArray()将放回的Object[]赋值到elementData上了,为什么还要进行判断呢?
            //因为c.toArray()返回的内容类型有可能不是Object[]数组,这是一个小bug,如果不进行判断处理的话,客户使用时会有隐患【参见精解5】
            if (elementData.getClass() != Object[].class)
                elementData = Arrays.copyOf(elementData, size, Object[].class);
        } else {
   
            //将空数组赋值给elementData
            this.elementData = EMPTY_ELEMENTDATA;
        }
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值