1.ArrayList继承的类和实现的接口
arraylist继承了AbstractList,实现了List接口、RandomAccess接口、Serializable接口
2.ArrayList类所包含的属性
(1)serialVersionUID
serialVersionUID适用于java序列化机制。简单来说,JAVA序列化的机制是通过 判断类的serialVersionUID来验证的版本一致的。在进行反序列化时,JVM会把传来的字节流中的serialVersionUID于本地相应实体类的serialVersionUID进行比较。如果相同说明是一致的,可以进行反序列化,否则会出现反序列化版本一致的异常,即是InvalidCastException。
private static final long serialVersionUID = 8683452581122892189L;
(2)DEFAULT_CAPACITY
默认初始容量为10
/**
* Default initial capacity.
*/
private static final int DEFAULT_CAPACITY = 10;
(3)EMPTY_ELEMENTDATA
将那句注释翻译下来为:用于空实例的共享空数组实例。说白了就是一个空数组
/**
* Shared empty array instance used for empty instances.
*/
private static final Object[] EMPTY_ELEMENTDATA = {};
(4)DEFAULTCAPACITY_EMPTY_ELEMENTDATA
空数组的默认容量
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
(5)elementData
定义一个临时数组,即传过来的数组
transient Object[] elementData;
(6)size
集合中所储存元素的个数
private int size;
3.ArrayList中的方法
1)构造方法
【1】有参构造
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);
}
}
方法中定义了一个初始容量initialCapacity
在if条件判断中:(1)初始容量大于0(即不为空)时,new一个初始容量大小的Object数组
(2)当初始容量等于0(即为空)时,将空数组赋值给elementData
(3)都不是上述两种情况,就抛出一个异常
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;
}
}
参数为Collection<? extends E> c,是一个集合
1.将原集合转化成数组
2.在if中判断数组的长度:若长度不为0,将原集合中的数据复制到新数组
若长度为0,返回一个空集合EMPTY_ELEMENTDATA
【2】无参构造
public ArrayList() {
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}
给elementData赋值一个空数组默认容量
2. add(E e)
public boolean add(E e) {
ensureCapacityInternal(size + 1); // Increments modCount!!
elementData[size++] = e;
return true;
}
[1]ensureCapacityInternal(int minCapacity)
private void ensureCapacityInternal(int minCapacity) {
ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
}
[2]ensureExplicitCapacity(int minCapacity)
这一步的目的是判断是否需要扩容
在if中判断最小容量与传进来的数组长度的大小,若最小容量大于传进来的数组长度,则调用grow()方法(具体方法见【4】)
private void ensureExplicitCapacity(int minCapacity) {
modCount++;
// overflow-conscious code
if (minCapacity - elementData.length > 0)
grow(minCapacity);
}
[3]calculateCapacity(Object[] elementData, int minCapacity)
这个方法的目的是获得最小容量
1.在参数中定义一个数组、一个最小容量
2.在if中判断传进来的数组是否与空数组的默认容量相等:
相等:返回默认容量与最小容量之间最大的那个
不相等:返回最小容量
private static int calculateCapacity(Object[] elementData, int minCapacity) {
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
return Math.max(DEFAULT_CAPACITY, minCapacity);
}
return minCapacity;
}
[4]grow(int minCapacity)
1.将传进来的数组长度定义为旧容量(oldCapacity)
2.将旧容量(oldCapacity)向右移一位,再加上原来的容量大小,即新容量(newCapacity)为原来的1.5倍
3.第一个判断中,将新容量(newCapacity)与最小容量作比较,若小于最小容量(代表扩容过小),则将最小容量(minCapacity)赋给新容量(newCapacity)
4.第二个判断中,将新容量(newCapacity)与MAX_ARRAY_SIZE作比较,若小于MAX_ARRAY_SIZE(代表扩容过大),则将hugeCapacity(int minCapacity)的返回值赋给新容量(newCapacity) (具体方法见【5】)
5.最后,将旧数组中的数据复制到新数组中(copyOf)
private void grow(int minCapacity) {
// overflow-conscious code
int oldCapacity = elementData.length;
int newCapacity = oldCapacity + (oldCapacity >> 1);
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity);
// minCapacity is usually close to size, so this is a win:
elementData = Arrays.copyOf(elementData, newCapacity);
}
[5]hugeCapacity(int minCapacity)
1.在if条件中,判断最小容量是否小于0:
若小于0:则抛出异常
否则:比较minCapacity与MAX_ARRAY_SIZE的大小,若大于(按源码中的顺序),则返回Integer.MAX_VALUE
若小于,则返回MAX_ARRAY_SIZ
private static int hugeCapacity(int minCapacity) {
if (minCapacity < 0) // overflow
throw new OutOfMemoryError();
return (minCapacity > MAX_ARRAY_SIZE) ?
Integer.MAX_VALUE :
MAX_ARRAY_SIZE;
}