1.ArrayList底层原理
答:ArrayList底层数据结构是一个动态数组。
2.ArrayList添加数据的过程?
答:ArrayList的初始长度是0,第一次添加数据是将数组容量初始化为10,该过程未进行扩容。当添加的数组容量超过10,ArrayList进行扩容,扩容的容量是原来的1.5倍。
private void add(E e, Object[] elementData, int s) {//e:要添加的元素 elementData:动态数组的名字 s:集合长度/现在元素应存入的位置
if (s == elementData.length)
elementData = grow();//调用grow()方法
elementData[s] = e;
size = s + 1;
}
private Object[] grow() { return grow(size + 1); }//调用无参构造,在无参构造中继续调用有参构造
private Object[] grow(int minCapacity) {//minCapacity=size+1 int oldCapacity = elementData.length;//将数组长度传给老容量 if (oldCapacity > 0 || elementData != DEFAULTCAPACITY_EMPTY_ELEMENTDATA) { int newCapacity = ArraysSupport.newLength(oldCapacity, minCapacity - oldCapacity, //至少新增的容量 oldCapacity >> 1 //默认新增容量大小 ); return elementData = Arrays.copyOf(elementData, newCapacity);//将第一个参数中的所有数据,全部拷贝到新数组中,按照第二个参数创建新数组 } else { return elementData = new Object[Math.max(DEFAULT_CAPACITY, minCapacity)]; } }
public static int newLength(int oldLength, int minGrowth, int prefGrowth) {
int prefLength = oldLength + Math.max(minGrowth, prefGrowth); //新数组的真正长度
if (0 < prefLength && prefLength <= SOFT_MAX_ARRAY_LENGTH) {
return prefLength;
} else {
return hugeLength(oldLength, minGrowth);
}
}
minGrowth:如果一次添加一个元素,minGrowth=1,此时扩容一个单位。
prefGrowth:如果一次添加多个元素,假如添加50个,prefGrowth=50,此时数组需要扩容50个单位。