对于ArrayList而言,它实现了List接口,底层使用数组保持所有数据,基本操作就是对数组的操作;
下面通过自己定义1个ArrayList的方式来分析下ArrayList的实现原理
构造器:
无参构造的时候,就是初始化本地的1个elementData;
我们可以看到
DEFAULTCAPACITY_EMPTY_ELEMENTDATA就是1个空数组,
而elementData则是实际存放和操作数据的数组对象,这里只是做个简单的初始化操作;
Add方法:
可以看到Add方法中主要就是2步操作
1:检查数组是否需要扩容
2:数组中插入1条数据
我们知道,数组在创建的时候就已经分配了长度了,并且是不可扩展的;
既然ArrayList的可变长度的,而ArrayList底部的实现又是数组,那我们接着看看ensureCapacityInternal()他是怎么实现的;
看程序的调用链,除开一些条件判断外,真正需要扩容的的其实是走到了grow()函数中去。那我们接着看看grow()函数都做了什么
grow函数中的逻辑也很简单,就是获取旧数组,将旧数组的长度*2后创建1个新的数组,并且将旧数组的数组copy到新数组中去;
在判断完是否需要需要数组扩容以后,我们就可以安心的在数组在添加元素了;
add方法除了可以添加1个对象外,还可以指定某个位置插入对象;
原理同add方法差不多,只是在数据的迁移上有些出入;
AddAll方法:
因为底层操作的是数组,所以在addAll方法中,第一步就是将传入的集合转化成数组;addAll是在集合的尾部追加数据,参照上面的代码迁移和追加数据即可;另外,addAll方法也支持在列表中某个位置插入一组数据,原理同add基本一致就不在重复了;
set方法和get方法,底层原理都是在elementData中取出索引位置对应的数据相对简单
来看下remove方法:
此方法是删除指定下标的元素
重要步骤:1计算numMoved,也就是计算出你删除的这个元素索引位置数组中存在的元素个数
2根据numMoved的值来进行旧数据的迁移
至此,ArrayList的增删改查基本功能的实现原理也掌握的差不多了。至于其他的API,比如contains,indexof等,底层的 操作就是对elementData数组的基本操作;