写点什么

ArrayList 源码分析 - 初始化

作者:zarmnosaj
  • 2022 年 5 月 14 日
  • 本文字数:1154 字

    阅读完需:约 4 分钟

ArrayList 源码分析-初始化

ArrayList 是我们经常会用到的一个类,并且也属于面试常问的问题。

ArrayList 底层结构

先看源码:


public class ArrayList<E> extends AbstractList<E>        implements List<E>, RandomAccess, Cloneable, java.io.Serializable {    private static final int DEFAULT_CAPACITY = 10;    private static final Object[] EMPTY_ELEMENTDATA = {};    transient Object[] elementData; // non-private to simplify nested class access    private int size;
......}
复制代码


ArrayList 底层就是一个数组,其中:


  1. DEFAULT_CAPACITY 表示数组的初始大小,默认为 10

  2. size 表示当前数组的大小

  3. modCount 统计当前数组被修改的版本次数,每次数组结构有变动时,例如调用 add()、remove(),modCount 的值就会跟随 +1。


ArrayList 其他特点,也是注释上的说明:


  1. ArrayList 内允许放入 null 值

  2. 新增元素时会有扩容机制

  3. 是非线程安全的

  4. 增强 for 循环,或者使用迭代器迭代过程中,如果数组大小被改变,会快速失败,抛出异常。

ArrayList 的初始化方法

无参初始化,源码:


    public ArrayList() {        this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;    }
复制代码


指定大小初始化,源码:


    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(Collection<? extends E> c) {        elementData = c.toArray();        if ((size = elementData.length) != 0) {            // c.toArray might (incorrectly) not return Object[] (see 6260652)            if (elementData.getClass() != Object[].class)                elementData = Arrays.copyOf(elementData, size, Object[].class);        } else {            // replace with empty array.            this.elementData = EMPTY_ELEMENTDATA;        }    }
复制代码


需要注意的是,其中 ArrayList 无参构造器初始化时,默认大小是空数组,并不是大家常说的 10,10 是在第一次 add 的时候扩容的数组值。

初始化中的一个 bug

在以上构造方法的指定初始数据初始化方法中,有一行注释 see 6260652,这是 Java 的一个 bug。


当初始化数据传入值不是 Object 类型时,转为 Object,调用 java.util.ArrayList#toArray()方法,得到 Object 数组,往 Object 数组赋值时会触发此 bug,不过已经在 java9 版本中修复。

用户头像

zarmnosaj

关注

还未添加个人签名 2020.02.06 加入

还未添加个人简介

评论

发布
暂无评论
ArrayList源码分析-初始化_5月月更_zarmnosaj_InfoQ写作社区