ArrayList内部用什么实现的?
回答这样的问题,不要只回答皮毛,可以再介绍一下ArrayList内部是如何实现数组的增删的,因为数组在创建的时候长度是固定的,那么就有个问题我们往ArrayList中不断地添加对象,它是如何管理这些数组呢?
ArrayList内部是用Object[]实现的。
一、构造函数
- 空参构造
public ArrayList(){ array = EmptyArray.OBJECT; }
array是一个Object[]类型。当我们new一个空参构造时系统调用了EmptyArray.OBJECT属性,EmptyArray仅仅是一个系统的类库,该类源码如下:
public final class EmptyArray{ private EmptyArray(){} public static final boolean[] BOOLEAN = new boolean[0]; public static final byte[] BYTE = new byte[0]; public static final char[] CHAR = new char[0]; public static final double[] DOUBLE = new double[0]; public static final int[] INT = new int[0]; public static final Class<?>[] CLASS = new Class[0]; public static final Object[] OBJECT = new Object[0]; public static final String[] STRING = new String[0]; public static final Throwable[] THROWABLE = new Throwable[0]; public static final StackTraceElement[] STACK_TRACE_ELEMENT = new StackTraceElement[0]; }
也就是说我们new一个空参ArrayList的时候,系统内部使用了一个new Object[0]数组。
-
含参构造 1
/** Constructs a new instance of {@code ArrayList} with the specified initial capacity. @param capacity the initial capacity of the {@code ArrayList}. */ public ArrayList (int capacity){ if(capacity < 0){ throw new IllegalArgumentException("capacity < 0: " + capacity); } array = (capacity == 0 ? EmptyArray.OBJECT : new Object[capacity]); }
该构造函数传入一个int值,该值作为数组的长度值。如果该值小于0,则抛出一个运行时异常。如果等于0,则使用一个空数组,如果大于0,则创建一个长度为该值的新数组。
-
含参构造2
/** * Constructs a new instance of {@code ArrayList} containing the elements of * the specified collection. * * @param collection * the collection of elements to add. */ public ArrayList(Collection<? extends E> collection) { if (collection == null) { throw new NullPointerException("collection == null"); } Object[] a = collection.toArray(); if (a.getClass() != Object[].class) { Object[] newArray = new Object[a.length]; System.arraycopy(a, 0, newArray, 0, a.length); a = newArray; } array = a; size = a.length; }
如果调用构造函数的时候传入一个Collection的子类,那么先判断该集合是否为null,为null则抛出空指针异常。如果不是则将该集合转换为数组a,然后将该数组赋值为成员变量array,将该数组的长度作为成员变量size。这里面它先判断a.getClass是否等于Object[].class,其实一般都是相等的,toArray方法是Collection接口定义的,因此其所有的子类都有这样的方法,list集合的toArray和Set集合的toArray返回的都是Object []数组。