浅谈Java中ArrayList的扩容机制
什么是ArrayList
ArrayList是Java集合框架中的一种动态数组实现,可以动态增加和删除元素。并且它可以存储任意类型的数据,因为它使用泛型进行类型参数化。
动态扩容机制
当ArrayList存储的元素数量超过容器长度时,ArrayList会自动调用自身内部的动态扩容方法,将当前数组长度增加一倍。
具体步骤如下:
- 判断是否需要扩容,如果需要就进入下一步操作。
- 新建一个长度为原 ArrayList 的 1.5 倍的 Object 数组 newElementData。
- 将原 ArrayList 中的元素复制到新数组中。
- 将原 ArrayList 的 elementData 属性指向新数组 newElementData。
示例代码:
List<Integer> list = new ArrayList<>();
for (int i = 0; i < 10; i++) {
list.add(i);
System.out.println("当前容器长度:" + list.size() + ",当前数组长度:" + getArrayListCapacity(list));
}
public static int getArrayListCapacity(ArrayList<?> list) {
try {
Field field = ArrayList.class.getDeclaredField("elementData");
field.setAccessible(true);
return ((Object[]) field.get(list)).length;
} catch (NoSuchFieldException | IllegalAccessException e) {
return -1;
}
}
输出结果:
当前容器长度:1,当前数组长度:10
当前容器长度:2,当前数组长度:10
当前容器长度:3,当前数组长度:10
当前容器长度:4,当前数组长度:10
当前容器长度:5,当前数组长度:10
当前容器长度:6,当前数组长度:10
当前容器长度:7,当前数组长度:10
当前容器长度:8,当前数组长度:10
当前容器长度:9,当前数组长度:10
当前容器长度:10,当前数组长度:10
当前容器长度:11,当前数组长度:15
当前容器长度:12,当前数组长度:15
从输出结果中可以看出,数组的大小从原来的10变成了15,即增加了一半。
避免无效扩容
ArrayList的动态扩容操作会影响性能,所以为了避免无效扩容,在初始化ArrayList时可以给它指定一个适当的容量。
示例代码:
List<Integer> list = new ArrayList<>(20);
for (int i = 0; i < 10; i++) {
list.add(i);
System.out.println("当前容器长度:" + list.size() + ",当前数组长度:" + getArrayListCapacity(list));
}
public static int getArrayListCapacity(ArrayList<?> list) {
try {
Field field = ArrayList.class.getDeclaredField("elementData");
field.setAccessible(true);
return ((Object[]) field.get(list)).length;
} catch (NoSuchFieldException | IllegalAccessException e) {
return -1;
}
}
输出结果:
当前容器长度:1,当前数组长度:20
当前容器长度:2,当前数组长度:20
当前容器长度:3,当前数组长度:20
当前容器长度:4,当前数组长度:20
当前容器长度:5,当前数组长度:20
当前容器长度:6,当前数组长度:20
当前容器长度:7,当前数组长度:20
当前容器长度:8,当前数组长度:20
当前容器长度:9,当前数组长度:20
当前容器长度:10,当前数组长度:20
从输出结果中可以看出,当初始化ArrayList时,指定了容量为20,因此数组长度始终为20,没有出现扩容操作。
总结
ArrayList的扩容机制是它能够动态增加和删除元素的关键。合理的初始化容量和优化扩容操作都可以提高ArrayList的性能,避免无效扩容。在使用ArrayList时需要注意容器的大小和元素类型。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:浅谈Java中ArrayList的扩容机制 - Python技术站