首页 > 编程知识 正文

arraylist实现(arraylist可以重复吗)

时间:2023-05-06 00:07:29 阅读:101357 作者:1205

采访者:“数组列表集合的默认长度是多少?”

完美答案:默认长度为10。但是ArrayList的默认长度与jdk版本不同。在JDK版本8之前,默认长度是10。在jdk8版本中,对ArrayList数组的默认长度进行了优化,将原来的默认长度10改为初始长度0。当我们第一次添加元素并需要分配数组空间时,jdk自动将初始数组长度扩展到10。这样有效减少了无用内存的占用!它利用数组扩展的特性来完成集合的这些功能,这也是ArrayList集合查询快,增删慢的原因!

知识摘要:

面临这个问题,所以一定不要直接回答默认长度是10或者0。

因为ArrayList集合起源于jdk的1.2版本,所以它在开始时的默认长度是JDK源代码中最初的10个长度。

经过多年的迭代,人们发现了问题,并在JDK8版本中进行了优化。初始长度为0。第一次添加元素时,需要实际分配数组空间。执行阵列扩展操作时,扩展长度为10。

优点:真正把数据插入数组,用的时候创建,或者重载,有效减少无用内存的占用。

源代码(您可以在完成源代码后了解jdk如何帮助您实现它)

默认大小的空实例的共享空数组实例。我们将其与空的ELEMENTDATA区分开来,以便在添加第一个元素时扩展所需的容量。

/**

*共享空阵列实例用于默认大小的空实例。我们

*将此与EMPTY_ELEMENTDATA区分开来,以了解何时充气多少

*添加了第一个元素。

*/

//一个空对象。如果使用默认构造函数来创建它,默认对象内容就是缺省值。

私有静态最终对象[]DEFAULTCAPACITY _ EMPTY _ element data={ };这是将元素插入数组时要扩展的默认长度10。

/**

*默认初始容量。

*/

私有静态最终int DEFAULT _ CAPACITY=10对象数组

/**

*存储数组列表元素的数组缓冲区。

*数组列表的容量是这个数组缓冲区的长度。任何的

* element data==DEFAULTCAPACITY _ EMPTY _ element data的空数组列表

*将在添加第一个元素时扩展为DEFAULT_CAPACITY。

*/

瞬态对象[]元素数据;//非私有以简化嵌套类访问空对象

//空对象

私有静态最终对象[] EMPTY_ELEMENTDATA=新对象[0];当前数组长度也可以理解为有效元素的数量。

//当前数组长度

私有int大小;数组的最大长度

//数组的最大长度

私有静态最终int MAX _ ARRAY _ SIZE=214748363900-1010add有两种方法,一种带有一个参数,另一种带有两个参数。接下来,我们将添加一个参数方法。

加法

add的主要执行逻辑如下:

1)确保使用的长度(大小)加上数组的1足以存储下一个数据。2)修改次数modCount增加1。如果当前数组的已用长度(大小)加1大于当前数组长度,则调用grow方法来增长数组。grow方法会将当前阵列的长度更改为原始容量的1.5倍。3)在确保新添加的数据存储在本地后,将新元素添加到大小的位置。4)返回加法成功布尔值。插入元素条目

//注意:这里的大小理解为有效元素的个数。

公共布尔加法

保证容量内部(大小为1);//判断产能扩张

element data[size]=e;//将插入的值放入数组中(有效元素的数量

+1) return true;//返回添加成功的布尔值true }

判断扩容入口

private void ensureCapacityInternal(int minCapacity) { //查看ensureExplicitCapacity和calculateCapacity方法源码 ensureExplicitCapacity(calculateCapacity(elementData, minCapacity)); } 1234 ensureExplicitCapacity private void ensureExplicitCapacity(int minCapacity) { modCount++;//忽略此句,这是父接口的计数器 // overflow-conscious code if (minCapacity - elementData.length > 0)//传入的参数(size+1)-Object数组长度>0的时候需要扩容 grow(minCapacity);//具体扩容方法,并查看扩容方法 }

grow

/** * Increases the capacity to ensure that it can hold at least the * number of elements specified by the minimum capacity argument. * * @param minCapacity the desired minimum capacity */ private void grow(int minCapacity) { // overflow-conscious code int oldCapacity = elementData.length;//原长度赋给oldCapacity int newCapacity = oldCapacity + (oldCapacity >> 1);//将数组长度扩容为原来的1.5倍 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);//复制数组元素到新长度的数组中 }

calculateCapacity

//确保添加的元素有地方存储,当第一次添加元素的时候this.size+1 的值是1,所以第一次添加的时候会将当前elementData数组的长度变为10 private static int calculateCapacity(Object[] elementData, int minCapacity) { if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {//Object数组长度==默认长度0时 return Math.max(DEFAULT_CAPACITY, minCapacity);//返回默认长度10和传入(size+1)的最大追 } return minCapacity;//如果Object数组长度不等于默认长度0时,直接返回(size+1) }

作者:Ziph

原文链接:https://blog.csdn.net/weixin_44170221/article/details/104661133

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。