jdk1.8 ArrayList源码
程序员文章站
2022-06-04 19:23:52
...
ArrayList有三个构造函数
1.指定初始化长度,如果长度小于0,抛出异常.大于等于0,创建对应长度的Object数组.
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);
}
}
2.无参构造函数,创建一个为空的Object数组
public ArrayList() {
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
3.一个指定collection的构造函数: ArrayList(Collection<? extends E> c)构造一个包含指定collection的元素的列表,这些元素是按照该collection的迭代器返回它们的顺序排列的。
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;
}
}
transient Object[] elementData
ArrayList的Ojbect数组用transient 修饰防止序列化. 序列化即将对象转换为字节序列写入IO流,可以用于保存到磁盘或是网络传输.
ArrrayList的序列化通过writeObject方法完成.因为elementData会动态扩容,数组里部分元素是空的,全部序列化会浪费性能.比如没有初始化数组长度,那么默认长度即为10,但是如果实际上只有五个元素,那么没必要全部序列化,只需要序列化那五个元素就行了.
private void writeObject(java.io.ObjectOutputStream s)
throws java.io.IOException{
// Write out element count, and any hidden stuff
int expectedModCount = modCount;
s.defaultWriteObject();
// Write out size as capacity for behavioural compatibility with clone()
s.writeInt(size);
// Write out all elements in the proper order.
for (int i=0; i<size; i++) {
s.writeObject(elementData[i]);
}
if (modCount != expectedModCount) {
throw new ConcurrentModificationException();
}
}
ArrayList在完成新增动作时赋值初始化长度.
public boolean add(E e) {
ensureCapacityInternal(size + 1); // Increments modCount!!
elementData[size++] = e; //添加对象时,自增size
return true;
}
进入ensureCapacityInternal
private void ensureCapacityInternal(int minCapacity) {
ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
}
//如果elementData初始化时是空,比较minCapacity和10的大小,返回较大值
private static int calculateCapacity(Object[] elementData, int minCapacity) {
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
return Math.max(DEFAULT_CAPACITY, minCapacity);
}
return minCapacity;
}
private void ensureExplicitCapacity(int minCapacity) {
modCount++; //定义于ArrayList的父类AbstractList,用于存储结构修改次数
// overflow-conscious code
if (minCapacity - elementData.length > 0)
grow(minCapacity);
}
数组扩容 采用位运算
private void grow(int minCapacity) {
// overflow-conscious code
int oldCapacity = elementData.length;
int newCapacity = oldCapacity + (oldCapacity >> 1);//新容量扩大到原容量的1.5倍,右移一位相关于原数值除以2。
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);
}