ArrayList数组扩容方式(基于jdk1.8)
ArrayList无参构造函数为:
public ArrayList() {
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}
而DEFAULTCAPACITY_EMPTY_ELEMENTDATA是一个空数组,即无参ArrayList创建时内部初始容量为0,
当向ArrayList中增加数据时,先检查elementData数组的大小,如果elementData数组已经无法在存放元素,需要进行扩容,具体的扩容方法为grow方法
public boolean add(E e) {
//检查elementData数组是否可以能够存放下一个元素,
ensureCapacityInternal(size + 1); // Increments modCount!!
elementData[size++] = e;
return true;
} private static int calculateCapacity(Object[] elementData, int minCapacity) {
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
//这种情况是无参构造方法创建的ArrayList,增加数据时elementData扩容为DEFAULT_CAPACITY(该值为10)大小的数组,
return Math.max(DEFAULT_CAPACITY, minCapacity);
}
return minCapacity;
} private void ensureCapacityInternal(int minCapacity) {
ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
} private void ensureExplicitCapacity(int minCapacity) {
modCount++; // overflow-conscious code
if (minCapacity - elementData.length > 0)
grow(minCapacity);
}
grow方法实现如下,每次增加的容量为 原本容量的一半
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);
}
测试程序如下:
private static void testArrayList() throws Exception {
List<String> list = new ArrayList<>();
Field field = ArrayList.class.getDeclaredField("elementData");
field.setAccessible(true);
for (int i = 0; i < 100; i++) {
Object[] data = (Object[]) field.get(list);
int before = data.length;
list.add(String.valueOf(i));
data = (Object[]) field.get(list);
int after = data.length;
if (before != after) {
System.out.println(String.format("增加第%s个元素时进行了扩容,原来内部数组大小为:%s,扩容后为:%s", i + 1, before, after));
}
}
}
测试结果如下:
增加第1个元素时进行了扩容,原来内部数组大小为:0,扩容后为:10
增加第11个元素时进行了扩容,原来内部数组大小为:10,扩容后为:15
增加第16个元素时进行了扩容,原来内部数组大小为:15,扩容后为:22
增加第23个元素时进行了扩容,原来内部数组大小为:22,扩容后为:33
增加第34个元素时进行了扩容,原来内部数组大小为:33,扩容后为:49
增加第50个元素时进行了扩容,原来内部数组大小为:49,扩容后为:73
增加第74个元素时进行了扩容,原来内部数组大小为:73,扩容后为:109
如果将ArrayList初始容量设置为5,即List<String> list = new ArrayList<>(5);
测试结果如下:
增加第6个元素时进行了扩容,原来内部数组大小为:5,扩容后为:7
增加第8个元素时进行了扩容,原来内部数组大小为:7,扩容后为:10
增加第11个元素时进行了扩容,原来内部数组大小为:10,扩容后为:15
增加第16个元素时进行了扩容,原来内部数组大小为:15,扩容后为:22
增加第23个元素时进行了扩容,原来内部数组大小为:22,扩容后为:33
增加第34个元素时进行了扩容,原来内部数组大小为:33,扩容后为:49
增加第50个元素时进行了扩容,原来内部数组大小为:49,扩容后为:73
增加第74个元素时进行了扩容,原来内部数组大小为:73,扩容后为:109
最新文章
- Android Fragment的使用
- 汇编学习(二)&mdash;&mdash;8086CPU
- Applescript 带参数调用某个App的方法
- codevs 1294 全排列 next_permuntation
- HTML要点(五)<;iframe>;标签
- ORA-15124 数据库启动阶段报错
- 【转】Maven实战(四)---多模块项目---JBOSS部署问题
- 利用Qt调用计算器
- Javascript参数传递中值和引用的一种理解
- 定义Foo() 函数,弹出对话框提示当前选中的是第几个单选框
- 【转】四步完成win7 ubuntu双系统安装(硬盘,无需光驱)
- Android 程式开发:(廿一)消息传递 —— 21.3 使用Intent发送短信
- Android OpenGL ES(三)OpenGL ES API 命名习惯 .
- 2 Java对象的创建过程
- 微信公众号_订阅号_access_token_创建菜单_菜单name+表情
- 接口自动化测试遭遇问题,excel中取出来的json串,无法使用requests去请求解决办法
- SpringMVC+JQuery实现头像编辑器
- XPATH语法(一)
- [工作记录] NDK: AKEYCODE_DEL not notified
- 如何在 Azure 中均衡 Windows 虚拟机负载以创建具有高可用性的应用程序