ArrayList底层原理
1.ArrayList动态扩容的方法?
- 使用空参创建集合,在底层创建一个长度默认为0的数组;
- 添加第一个元素时,底层会创建一个数组长度为10的数组;
- 存满的时候,数组会自动扩容1.5倍;
- 如果1.5倍的数组长度还放不下的时候,则新创建的数组长度应该是实际的数组长为准,比如现在的数组的长度为10,要添加100的元素,那么需求的数组长度为110;
2.源代码
//transient 关键字修饰时,表示它不会被默认的序列化和反序列化机制所处理。
transient Object[] elementData;
//空参构造
public ArrayList() {
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}
//向数组添加元素,size则为下一个需要添加元素的位置
private void add(E e, Object[] elementData, int s) {
if (s == elementData.length)
elementData = grow();
elementData[s] = e;
size = s + 1;
}
//数组扩容的方法
private Object[] grow(int minCapacity) {
int oldCapacity = elementData.length;
if (oldCapacity > 0 || elementData != DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
int newCapacity = ArraysSupport.newLength(oldCapacity,
minCapacity - oldCapacity, /* minimum growth */
oldCapacity >> 1 /* preferred growth */);
return elementData = Arrays.copyOf(elementData, newCapacity);
} else {
return elementData = new Object[Math.max(DEFAULT_CAPACITY, minCapacity)];
}
}
private Object[] grow() {
return grow(size + 1);
}
public static int newLength(int oldLength, int minGrowth, int prefGrowth) {
// assert oldLength >= 0
// assert minGrowth > 0
int newLength = Math.max(minGrowth, prefGrowth) + oldLength;
if (newLength - MAX_ARRAY_LENGTH <= 0) {
return newLength;
}
return hugeLength(oldLength, minGrowth);
}
private static int hugeLength(int oldLength, int minGrowth) {
int minLength = oldLength + minGrowth;
if (minLength < 0) { // overflow
throw new OutOfMemoryError("Required array length too large");
}
if (minLength <= MAX_ARRAY_LENGTH) {
return MAX_ARRAY_LENGTH;
}
return Integer.MAX_VALUE;
}