ArrayList源码解析:ArraysList的字段属性和构造函数
ArrayList源码解析
arrayList就是动态数组,可以动态的添加和减少元组,实现了ICollection和Ilist接口以及灵活的设置数组的大小。
2. ArraysList的字段属性
private static final long serialVersionUID = 8683452581122892189L;
/**
* 保存数据的集合的默认长度
*/
private static final int DEFAULT_CAPACITY = 10;
/**
* 一个空的数组实例
*/
private static final Object[] EMPTY_ELEMENTDATA = {};
/**
* 也是一个空的数组实例,和EMPTY_ELEMENTDAT空数组相比是用于了解添加元素时数组膨胀多少。
*/
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
/**
* 存储ArrayList存储的元素,集合的长度就是这个数组的长度。
* 当elementData==DEFAULTCAPACITY_EMPTY_ELEMENTDATA时将会清空ArraysList
* 当添加第一个元素的时候,elementData将会扩展到DEFAULT_CAPACITY大小,也就是说在刚开始创建的时候不是10个,而是在第一次添加的时候才会变为大小10
*/
transient Object[] elementData; // 不是私有的,方便其他类访问,将不需要序列化的属性前添加关键字transient,序列化对象的时候,这个属性就不会被序列化。回想ArrayList的自动扩容机制,elementData数组相当于容器,当容器不足时就会再扩充容量,但是容器的容量往往都是大于或者等于ArrayList所存元素的个数。比如,现在实际有了8个元素,那么elementData数组的容量可能是8x1.5=12,如果直接序列化elementData数组,那么就会浪费4个元素的空间,特别是当元素个数非常多时,这种浪费是非常不合算的。所以ArrayList的设计者将elementData设计为transient,然后在writeObject方法中手动将其序列化,并且只序列化了实际存储的那些元素,而不是整个数组。见https://www.cnblogs.com/vinozly/p/5171227.html
/**
* 表示集合的长度
*/
private int size;
3. 构造函数
通过指定initialCapacity,可以构造指定初始容量的集合。这里可以发现在源码中,通过区分参数区间来划分不同情况,而不是通过一种流程来直接得出相应的结果的思想很重要。
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);
}
}
在无参构造函数中,将创建一个DEFAULTCAPACITY_EMPTY_ELEMENTDATA声明的数组,这里的数组容量是0,而不是很多人认为的10.当数组开始增加元素时才会扩容到10。
public ArrayList() {
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}
此构造函数,可以将已有的集合复制到ArrayList。当集合的大小为0的时候,则直接创建一个DEFAULTCAPACITY_EMPTY_ELEMENTDATA声明的数组,这里的数组容量是0。
public ArrayList(Collection<? extends E> c) {
Object[] a = c.toArray();
if ((size = a.length) != 0) {
if (c.getClass() == ArrayList.class) {
elementData = a;
} else {
elementData = Arrays.copyOf(a, size, Object[].class);
//copyOf用于拷贝数组元素。底层采用System.arraycopy实现,是一种本地方法。
}
} else {
// replace with empty array.
elementData = EMPTY_ELEMENTDATA;
}
}