简介
java中的线性表容器,是一种顺序表的结构,核心是用一个数组来对数据进行存储,同时也是一个容器,可以实现数据的动态存储。ArrayList中使用了泛型的定义,所以在实际的存储中存储的对象不能是基本类型(int,double等)。
基本操作
先从一些基本设计来看:
transient Object[] elementData;//实际用于存储的数组
private static final int DEFAULT_CAPACITY = 10;//默认的容器容量
private int size;//实际的数量
这里有一个区分一个是数据的数量,表述已经装入了这么多数量的数据,一个是容器的容量表示目前开辟的内存空间可以装这么多的数据。既然是一个顺序表的结构我们再看看其基本的操作。
初始化(构造函数)
这个类提供了三个构造函数。
默认生成空的线性表:
public ArrayList() {
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}
这里的空的表是初始化时将表置空,还有一个空表是在之后操作时表中没有数据了,为了区分这两个逻辑使用了两个引用加以区分。
private static final Object[] EMPTY_ELEMENTDATA = {
};//空的表
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {
};
//初始化时的空表,这时的容器容量为默认容量。
自定义容器大小的初始化,在初始化的时候不使用默认的容量初始化数组:
public ArrayList(int initialCapacity) {
if (initialCapacity > 0) {
//判断传入的大小是否合法
this.elementData = new Object[initialCapacity];
} else if (initialCapacity == 0) {
//如果是0就是建立空表
this.elementData = EMPTY_ELEMENTDATA;
} else {
//异常处理
throw new IllegalArgumentException("Illegal Capacity: "+ initialCapacity);
}
}
最后一个构造函数是以一个原有容器中的数据为基础创建顺序表:
public ArrayList(Collection<? extends E> c) {
elementData = c.toArray();//类型转换
if ((size = elementData.length) != 0) {
if (elementData.getClass() != Object[].class)
//转换之后的类型可能不是Object数组,再使用Arrays.copyOf()方法转化。
elementData = Arrays.copyOf(elementData, size, Object[].class);
} else {
//如果传入的是个空的容器就设置一个空表
this.elementData = EMPTY_ELEMENTDATA;
}
}
Collection这个接口为所有容器提供了一些共有的操作定义
ArrayList实现了List接口,而Collection是所有相关容器接口的父接口。
所以使用Collection可以代指所有与容器相关的类。
toArray方法是Collection接口中定义的,可以将相关的数据转换为数组。当然ArrayList也实现了这个方法。但是实际的实现对象是Arrays类。
public Object[] toArray() {
return Arrays.copyOf(elementData, size);
}
再到Arrays中看看:
//保持默认类型的转换
public static <T> T[] copyOf(T[] original, int newLength) {
return (T[]) copyOf(original, newLength, original.getClass());
}
//指定类型的转换
public static <T,U> T[] copyOf(U[] original, int newLength, Class<? extends T[]> newType) {
@SuppressWarnings("unchecked")
//根据出传入的类型和大小size来初始化一个数组
//如果不是Object类型就获取其默认类型(反射),并完成数组的空间开辟
T[] copy = ((Object)newType == (Object)Object[].class)
? (T[]) new Object[newLength]