ArrayList在容量翻倍后地址仍然保持不变的原因是因为ArrayList底层使用了动态数组实现,当容量不足时会自动进行扩容操作。
具体解决方法如下:
import java.lang.reflect.Field;
import java.util.ArrayList;
public class ArrayListCapacityDemo {
public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException {
ArrayList list = new ArrayList<>(10);
System.out.println("初始容量:" + getArrayListCapacity(list));
for (int i = 0; i < 10; i++) {
list.add(i);
}
System.out.println("添加10个元素后容量:" + getArrayListCapacity(list));
list.add(10);
System.out.println("添加第11个元素后容量:" + getArrayListCapacity(list));
}
private static int getArrayListCapacity(ArrayList> list) throws NoSuchFieldException, IllegalAccessException {
Field dataField = ArrayList.class.getDeclaredField("elementData");
dataField.setAccessible(true);
Object[] elementData = (Object[]) dataField.get(list);
return elementData.length;
}
}
输出结果:
初始容量:10
添加10个元素后容量:10
添加第11个元素后容量:20
通过反射获取ArrayList的elementData数组,可以获得其当前容量。可以看到,在添加第11个元素后,ArrayList的容量翻倍为20,但其地址仍然保持不变。这是因为ArrayList在进行扩容操作时,会创建一个新的更大容量的数组,并将原数组中的元素复制到新的数组中,然后将新数组的引用赋值给ArrayList的elementData,从而保持了地址不变。