数据结构定义
从数据结构的角度来说,ArrayList
是线性表基于java的顺序表示和实现,数据结构中定义其是一组地址连续的存储单元,所以其内部其实是数组
我们可以在顺序表中随意的获取指定位置的数据,即遍历读取非常方便,在其末尾追加元素也非常方便,而且可以根据需要增长或缩短其长度。
当然我们也可以在指定位置插入元素,但是通常不建议这样使用
如图所示:在n+1
长度的数组中,在i处插入一个元素,我们要将i后面的所有元素全部向后移动,如果在移动之前我们检测,现有数组中的元素已满,则先需要扩展数组,然后在进行移动,最后在i
处插入元素,所以其性能并不高!
接下来一点一滴的学习ArrayList,其中的泛型全部用Integer类型
- 属性
/**
* ArrayList初始容量
*/
private static final int DEFAULT_CAPACITY = 10;
private static final Object[] EMPTY_ELEMENTDATA = {};
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
//容器中真正用于存储数据的数组
transient Object[] elementData;
// 容器中元素的个数
private int size;
- 构造方法学习
ArrayList有三个构造方法
ArrayList()
ArrayList(int initialCapacity)
ArrayList(Collection<? extends E> c)
1.无形参的构造方法使用
ArrayList<Integer> list = new ArrayList<Integer>();
源码解析
public ArrayList() {
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}
当使用无形参的构造方法初始化ArrayList对象时,将静态属性DEFAULTCAPACITY_EMPTY_ELEMENTDATA
赋值给缓存数组
2.指定初始容量的构造方法使用
ArrayList<Integer> list = new ArrayList<Integer>(5);
源码解析
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为容器的初始容量,当前初始容量initialCapacity大于0时,创建一个长度为初始容量initialCapacity的Object数组,赋值给缓存数组elementData,如果初始容量为0,则将静态属性EMPTY_ELEMENTDATA
赋值给缓存数组,初始容量小于0时,抛出异常
3.以其他容器作为参数的构造方法
public ArrayList(Collection<? extends E> c) {
//将参数中的容器转换为数组,赋值给elementData
elementData = c.toArray();
//在判断条件中将elementData的长度赋值给size,修改当前ArrayList的长度
if ((size = elementData.length) != 0) {
//转换后,elementData中有元素,当元素的类型不适Object类型时,将其中的元素全部拷贝到长度为size的Object数组中,并将最后结果赋值给elementData
if (elementData.getClass() != Object[].class)
elementData = Arrays.copyOf(elementData, size, Object[].class);
} else {
//形参转换为数组后,数组中没有元素,则将EMPTY_ELEMENTDATA赋值给elementData,使得elementData仍然是一个空的Object数组
this.elementData = EMPTY_ELEMENTDATA;
}
}