Java集合之ArrayList扩容

JDK1.8

一,ArrayList的构造函数有三种

1.public ArrayList(int initialCapacity) {...},

 

如果传入的参数initialCapacity合法的话,ArrayList会在elementData属性中存入一个Object数组,长度为传参initialCapacity,这个elementData是什么呢:

 

翻译为:

存储ArrayList元素的数组缓冲区。ArrayList的容量是这个数组缓冲区的长度。任何空的ArrayList的elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA

当添加第一个元素时,长度将扩展为DEFAULT_CAPACITY

ArrayList底层实现是数组,所以elementData就是用来存放你的数组数据的,大家都知道ArrayList是个泛型类,数据元素类型检查已经在编译期完成,所以新建的elementData是一个Object数组,这个数组缓存区可以存放任意类型的元素。

2.public ArrayList() {...}

 

其中DEFAULTCAPACITY_EMPTY_ELEMENTDATA:

 

翻译为:

用于默认大小的空实例的共享空数组实例。我们将其与EMPTY_ELEMENTDATA区分开来,以便知道何时膨胀多少添加第一个元素。

结合上文的elementData,就知道当新建空的ArrayList时,数组缓冲区elementData存放的是DEFAULTCAPACITY_EMPTY_ELEMENTDATA,也就是{},当添加第一个元素add()时,长度将会扩展为DEFAULT_CAPACITY,也就是ArrayList的初始容量10,即Object[10]。

3.public ArrayList(Collection<? extends E> c) {...}

 

这种情况是传参为集合的情况,ArrayList会将传参的集合转为数组toArray,并赋给elementData,其中toArray返回的就是一个Object数组

 

二,ArrayList的扩容

看对ArrayList增加元素的时候,用的方法:add

在ensureExplicitCapacity中,当minCapacity大于elementData的长度的时候(比如初始长度10),就需要扩容。看代码minCapacity为calculateCapacity(elementData, minCapacity)返回的值,看代码calculateCapacity方法返回的是传入的值size+1,或者当elementData为新建的{},将对其进行第一次扩容,即10。

扩容的方法:grow()

可以看到,一次扩容为oldCapacity + (oldCapacity >> 1),然后elementData = Arrays.copyOf(elementData, newCapacity);,会新建一个数组,然后将原来的elementData拷贝进去。

最后elementData[size++] = e;将新添加的元素放入数组缓冲区elementData

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
ArrayList扩容原理是基于动态数组的机制。当ArrayList中的元素数量超过了当前容量时,它会创建一个新的数组,并将原来的元素复制到新数组中。新数组的容量通常是原数组容量的两倍。这样可以确保在添加新元素时不需要频繁地进行数组的扩容操作,提高了性能。 下面是一个简单的代码示例,展示了ArrayList扩容机制: ```java import java.util.ArrayList; public class ArrayListDemo { public static void main(String[] args) { ArrayList<Integer> list = new ArrayList<>(); for (int i = 0; i < 20; i++) { list.add(i); System.out.println("Size: " + list.size() + ", Capacity: " + getCapacity(list)); } } private static int getCapacity(ArrayList<?> list) { try { java.lang.reflect.Field field = ArrayList.class.getDeclaredField("elementData"); field.setAccessible(true); return ((Object[]) field.get(list)).length; } catch (Exception e) { e.printStackTrace(); return -1; } } } ``` 请注意,ArrayList扩容是自动进行的,并且你不需要显式地调用扩容方法。ArrayList会在需要时自动进行扩容,并在内部处理相关操作。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [Arraylist扩容机制原理是什么?](https://blog.csdn.net/Blue92120/article/details/130841825)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值