ArrayList
1,为什么要实现RandomAccess接口,简单的的说为了通过判断循环接收的集合是否实现该类,从而选择使用for循环还是迭代器循环。参考博文:https://blog.csdn.net/weixin_39148512/article/details/79234817
2,ArrayList的构造方法
2.1 无参构造放方法 : 默认一个空数组。
/**
* Constructs an empty list with an initial capacity of ten.
*/
public ArrayList() {
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}
2.2 有参的构造方法
/**
* Constructs an empty list with the specified initial capacity.构造具有指定初始容量的空列表。
*
* @param initialCapacity the initial capacity of the list
* @throws IllegalArgumentException if the specified initial capacity
* is negative
*/
public ArrayList(int initialCapacity) { //要new的集合长度
if (initialCapacity > 0) {//入参大于0,创建一个和入参同等大小的数组
this.elementData = new Object[initialCapacity];
} else if (initialCapacity == 0) { //入参等于0,创建一个空数组
this.elementData = EMPTY_ELEMENTDATA;
} else { //(要是传负数) 非法参数异常
throw new IllegalArgumentException("Illegal Capacity: "+
initialCapacity);
}
}
3,ArrayList的扩容机制
/**
* Default initial capacity. 数组默认初始化长度
*/
private static final int DEFAULT_CAPACITY = 10;
/**
* The array buffer into which the elements of the ArrayList are stored.
* The capacity of the ArrayList is the length of this array buffer. Any
* empty ArrayList with elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA
* will be expanded to DEFAULT_CAPACITY when the first element is added.
*/
/**
存储ArrayList元素的数组缓冲区。 ArrayList的容量是此数组缓冲区的长度。 任何 使用elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA清空ArrayList
添加第一个元素时,将扩展为DEFAULT_CAPACITY。
*/
transient Object[] elementData; // non-private to simplify nested class access
当数组添加第一个元素时,集合才会初始化默认长度10
//① list的add方法 当添加一个元素时,会调用ensureCapacityInternal 方法判断该lsit是否需要扩容
public boolean add(E e) {
ensureCapacityInternal(size + 1); // Increments modCount!!
elementData[size++] = e;
return true;
}
//② elementData缓冲数组就是ArrayList的长度
private void ensureCapacityInternal(int minCapacity) {
//缓冲数组是不是等于默认空数组
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
//如果是,最小扩容值选择 DEFAULT_CAPACITY=10和minCapacity最大的一个,所以会说
//ArrayList初始化大小为10 的情况
minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
}
ensureExplicitCapacity(minCapacity);
}
/**
* Increases the capacity of this <tt>ArrayList</tt> instance, if
* necessary, to ensure that it can hold at least the number of elements
* specified by the minimum capacity argument.
*
* @param minCapacity the desired minimum capacity
*/
//如有必要,增加此<tt> ArrayList </ tt>实例的容量,以确保它至少可以容纳由minimum capacity参数指
//定的元素数。
public void ensureCapacity(int minCapacity) {
//判断elementData是否是默认空数组,如果不是minExpand为0,
//如果是minExpand=DEFAULT_CAPACITY=10
int minExpand = (elementData != DEFAULTCAPACITY_EMPTY_ELEMENTDATA)
// any size if not default element table
? 0
// larger than default for default empty table. It's already
// supposed to be at default size.
: DEFAULT_CAPACITY;
if (minCapacity > minExpand) {
ensureExplicitCapacity(minCapacity);
}
}
private void ensureExplicitCapacity(int minCapacity) {
modCount++;
// 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);
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);
}