1 ArrayList简介
ArrayList是一个数组队列,相当于动态数组。与JAVA中的数组相比,它的容量能动态增长。它继承于AbstractList,实现了List,RandomAccess,Clone,java.io.Seriaizable这些接口。
ArrayList继承了AbstractList,实现了List。它是一个数组队列,提供了相关的添加,删除,修改,遍历等功能。
ArrayList实现了RandomAccess接口,提供了随机访问功能。我们可以通过元素的序号快速获取元素对象,这就是随机访问。
ArrayList实现了Cloneable接口,覆盖了函数clone,能被克隆。
ArrayList实现了java.io.Serializable接口,这意味着ArrayList支持序列化,能通过序列化去传输。
ArrayList的操作不是线程安全的,建议在单线程中使用,而在多线程可以选择CopyOnWriteArrayList,Vector不建议使用(大部分方法直接被synronized直接修饰)
2 ArrayList源码分析
ArrayList说明支持泛型的。
ArrayList继承了抽象类AbstractList,而让AbstractList先实现了List接口,而不是让ArrayList直接继承List。
主要原因:接口中全是抽象的方法,而抽象类中可以有抽象方法,也有普通的方法,利用了这一点,让AbstractList去实现接口中一些通用的方法,而具体的类ArrayList继承了AbstractList,拿到一些通用的方法,然后自己可以再加上一些普通方法的逻辑。这样就把继承结构最底层的类中通用的方法接口都实现了。让代码更简洁。
实现了RandomAccess接口,在ArrayList中我们可以通过元素的序号快速获取元素对象,这就是快速随机访问。
实现了Cloneable接口,就可以使用Object.clone方法了。
实现了Serializable:表示该类具有序列化功能,该类可以被序列化,就是能够从类变成字节流传输,然后还能从字节流变成原来的类。
类的属性:
重要属性transient Object[] elementData 它的length代表ArrayList的容量。
构造方法:
ArrayList(int initialCapactity):构造一个指定容量initialCapactity的空ArrayList,这是一个带初始容量大小的有参构造函数。
ArrayList():构造一个初始容量为10的空列表,如果我们创建ArrayList对象的时候不传入参数,则使用无参构造方法创建ArrayList对象,从前面我们知道DEFAULTCAPACITY_EMPTY_ELEMENTDATA是一个空的Object[],这个空的Object[]会给个默认容量为10,但是现在我们是没看到这个容量为10,答案是第一次调用add()方法时,elementData将会变成默认的长度10。这个后面也会提到。
主要方法:
get()方法:
先越界检出,然后返回elementData数组的索引index。
set()方法
从elementData数组中取出旧值,然后把传进来的element赋值给elementData[index],然后返回旧值,看来这个方法是有返回值的,返回的是旧值。
add()方法:
有两个,一个带一个参数的,一个是带两个参数的。
先分析add(E e)这个方法。
先调用了确保内部容量方法,如果ArrayList是通过无参构造方法创建的话,此时size为0,然后size+1作为参数传递给ensureCapacityInternal方法。
由于是通过无参构造的那么minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);这行就会执行。接着就是minCapacity = DEFAULT_CAPACITY也就是10。
接着调用ensureExplicitCapacity(10),当最小容量10>数组容量数组的长度时,那么久进行扩容调用grow方法。
先获取当前数组的容量
进行扩容,新的容量=当前容量+当前容量/2,也就是扩容一次是1.5倍。
如果扩容后的容量还是小于想要的最小容量,那么直接将最小容量赋值给新的容量。
后面是扩容的容量临界值处理。
新的容量大小确定好之后,就copy数组,改变容量大小。
add(E e)第二种情况就是调用了有参构造方法传入了容量值。
add(int index, E element)方法:
越界检查,确保容量
对数组进行复制处理,目的就是空出index的位置插入element,并将index的元素位移一个位置
将指定的index位置赋值
ArrayList实际大小加1。
remove方法:
结构性修改次数+1
记录索引处的元素
计算删除元素,需要左移的元素个数
如果有需要左移的元素,就移动
size减1,然后将索引为size-1处的元素设为null,为了让GC起作用,显式地将最后一个位置为null值。
最后将旧值返回
indexOf()方法:返回此列表中指定元素的第一个出现项的索引,如果该列表不包含该元素,则返回-1。
分null和不为null两个逻辑,就是遍历elementData数组,找到了就返回index。这里看出来对ArrayList的操作都是对elementData数组操作。
clear()方法:
modCount++;检测快速失败的一种标志该变量加1
循环遍历赋值为null
ArrayList的大小设置为0
网友评论