elementData是ArrayList底层的数据结构,即Object数组;transient关键字表示该变量无法被序列化,防止序列化破坏ArrayList的封装性
size是ArrayList对象的有效元素大小,当size增加到数组的容量时,将会触发扩容
这是ArrayList从AbstarctList继承来的属性,表示结构变化次数,每次扩容、删除等都会引起modCount的改变,它用于迭代器的快速失败,如果在迭代过程中出现了对ArrayList的修改导致modCount变化了,即结构发生变化,则迭代器会抛出Concurrent Modification Exception
通过空参构造器创建的ArrayList底层是一个空数组,在第一次添加元素时,这个常量将会被用于判断是否是空参构造的ArrayList,如果是空参构造的数组,在第一次添加元素进行扩容时,会被扩容为10
通过传入一个int类型可以指定底层数组的初始大小,现讨论传入0的特殊情况,这里底层同样会被初始化为空数组,但是区别于空参构造器,两者指向的并不是同一个对象,所以这里不会像空参构造一样在第一次扩容为10
因为ArrayList底层使用的是Object数组,所以这里将数组转成Object类型
由此可见,ArrayList的set方法只能用来修改元素,不能用来增加元素,如果set方法传入的index在list长度之外,会在rangeCheck时报错IndexOutOfBoundsException
注意,这里的两个toArray方法不光实现了List接口还实现了AbstractCollection接口,可能有疑问实现的到底是哪个接口的方法,其实多虑了,这两个接口中任何一个类型的引用都可以传入ArrayList实例来调用这一段方法,下面这段代码佐证了这一点
public class Test {
public static void main(String[] args) throws Exception {
Method m = Class.forName("A").getDeclaredMethod("a");
Method m2 = Class.forName("B").getDeclaredMethod("a");
C c = new C();
m.invoke(c);
m2.invoke(c);
}
}
interface A{
void a();
}
interface B{
void a();
}
class C implements A,B{
@Override
public void a() {
System.out.println("a");
}
}
ArrayList中定义了两个内部迭代器类:Itr、ListItr,其中Itr实现了Iterator接口,ListItr是Itr的子类
属性
构造器
方法
ListItr是Itr的优化版本
构造器
方法
ArrayList中还有一个内部类SubList,用于从ArrayList中截取部分子视图
属性
子视图的方法和ArrayList基本一致,不做过多重复的分析,子视图的每一次操作都是利用ArrayList.this.elementData进行的,所以会直接修改ArrayList
ArrayListSpliterator是1.8加入的分割迭代器,相较于普通的Iterator迭代器,它的资源消耗更少,不需要next和hasNex配合,一个tryAdvance操作就可以完成迭代,而且分割迭代器还可以进行分区迭代
属性
构造器
方法