arraylist扩容是创建新数组吗 java_arraylist扩容机制要怎么实现?arraylist怎么扩容…「建议收藏」

arraylist扩容是创建新数组吗 java_arraylist扩容机制要怎么实现?arraylist怎么扩容…「建议收藏」ArrayList大家都知道了吧,这是一个动态数组。以java语言来说,数组是定长的,在被创建之后就不能被加长或缩短了,因此,了解它的扩容机制对使用它尤为重要。下面,我们就一起来看看它的扩容机制是怎么实现的吧。首先我们知道,ArrayList有着三种初始化方式:1)指定大小初始化publicArrayList(intinitialCapacity)2)传入一个Collection对象初始化,并…

大家好,又见面了,我是你们的朋友全栈君。

ArrayList大家都知道了吧,这是一个动态数组。以java语言来说,数组是定长的,在被创建之后就不能被加长或缩短了,因此,了解它的扩容机制对使用它尤为重要。下面,我们就一起来看看它的扩容机制是怎么实现的吧。

首先我们知道,ArrayList有着三种初始化方式:

1)指定大小初始化public ArrayList(int initialCapacity)

2)传入一个Collection对象初始化,并将对象中的数据添加到ArrayList中public ArrayList(Collection c)

3)默认构造函数初始化public ArrayList()

ArrayList扩容机制发生在add()方法调用的时候,从下面的代码我们可以看出当使用无参构造函数创建ArrayList时,它的默认长度会为0private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};

public ArrayList()

{

this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;

}

下面是add()方法的源码:public boolean add(E e)

{

//扩容

ensureCapacityInternal(size + 1); // Increments modCount!!

elementData[size++] = e;

return true;

}

根据以上我们可以看到,ensureCapacityInternal()是用来扩容的,形参为最小扩容量,进入此方法后:private void ensureCapacityInternal(int minCapacity)

{

ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));

}

通过方法calculateCapacity(elementData, minCapacity)来获取:private static int calculateCapacity(Object[] elementData, int minCapacity)

{

//如果传入的是个空数组则最小容量取默认容量与minCapacity之间的最大值

if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA)

{

return Math.max(DEFAULT_CAPACITY, minCapacity);

}

return minCapacity;

}

ensureExplicitCapacity方法可以判断是否需要扩容:

private void ensureExplicitCapacity(int minCapacity)

{

modCount++;

// 如果最小需要空间比elementData的内存空间要大,则需要扩容

if (minCapacity – elementData.length > 0)

//扩容 grow(minCapacity);

}

下面是重点来了,ArrayList扩容机制关键方法grow():private void grow(int minCapacity)

{

// 获取到ArrayList中elementData数组的内存空间长度

int oldCapacity = elementData.length;

// 扩容至原来的1.5倍

int newCapacity = oldCapacity + (oldCapacity >> 1);

// 再判断一下新数组的容量够不够,够了就直接使用这个长度创建新数组,

// 不够就将数组长度设置为需要的长度

if (newCapacity – minCapacity 

newCapacity = minCapacity;

//若预设值大于默认的最大值检查是否溢出

if (newCapacity – MAX_ARRAY_SIZE > 0)

newCapacity = hugeCapacity(minCapacity);

// 调用Arrays.copyOf方法将elementData数组指向新的内存空间时newCapacity的连续空间

// 并将elementData的数据复制到新的内存空间

elementData = Arrays.copyOf(elementData, newCapacity);

}

因此,我们可以清晰看出ArrayList扩容的本质其实就是计算出新的扩容数组的size后实例化它,并将原有数组内容复制到新数组中去。

以上就是关于ArrayList扩容机制的全部内容了,如果你还想要了解更多有关ArrayList相关的java常见问答知识,就快来关注我们的网站吧。

推荐阅读:

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/143995.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • A Singular Value Thresholding Algorithm for Matrix Completion

    A Singular Value Thresholding Algorithm for Matrix Completion前提假设假设存在一个未知的方阵M∈Rn×nM\inR^{n\timesn}M∈Rn×n,其中存在有mmm个采样得到的实例:{Mij:(i,j)∈Ω}\{M_{ij}:(i,j)\in\Omega\}{Mij​:(i,j)∈Ω},其中Ω\OmegaΩ是基数为mmm的随机子集。换句话说,就是在MMM中,存在mmm个已知的元素。前言大部分秩为rrr的矩阵MMM可以通过求解下面的优化问题来解决:minimize⁡∥X∥∗ subject to Xij=Mij,(i,j)∈

    2022年5月29日
    33
  • 老王讲二进制 & 0xFF;「建议收藏」

    老王讲二进制 & 0xFF;「建议收藏」$a=2;$b=($a<<6)&0xFF;var_dump($b);die;代码如上 最后结果是128。   $a  二进制左移6位 相当于$a*2^6(2的6次方)。现在告诉你后边的  &0xFF是什么鬼东西。这个东西的有无并不会影响计算结果,但严格意义上说应该有。因为前边的位移运算是二进制算法,计算结果是一个二进制数据,byte类型的

    2022年6月19日
    27
  • python Debug 单步调试[通俗易懂]

    python Debug 单步调试

    2022年1月29日
    46
  • VS2019 Qt开发环境搭建与配置

    VS2019 Qt开发环境搭建与配置Qt是很优秀的图形界面跨平台开发框架,开发语言可以用C++,也可以用python,建议使用C++。windows上Qt开发环境可以使用QtCreator,也可以使用VS+Qt,VS开发调试功能强大,本篇介绍VS2019+Qt5.14开发环境的配置,其它版本的类似。VS下载链接:https://visualstudio.microsoft.com/zh-hans/vs/VS2019C++主要安装模块:不…

    2022年5月16日
    37
  • windows常用端口号,以及服务对应的端口号「建议收藏」

    windows常用端口号,以及服务对应的端口号「建议收藏」查看端口在windows2000/xp/server2003中要查看端口,可以使用netstat命令:依次点击“开始→运行”,键入“cmd”并回车,打开命令提示符窗口。在命令提示符状态下键入“netstat-a-n”,按下回车键后就可以看到以数字形式显示的tcp和udp连接的端口号及状态。小知识:netstat命令用法命令格式:netstat-a-e…

    2025年8月27日
    7
  • 版本号命名规范[通俗易懂]

    版本号命名规范[通俗易懂]写在前面:本文章旨在总结备份、方便以后查询,由于是个人总结,如有不对,欢迎指正;另外,内容大部分来自网络、书籍、和各类手册,如若侵权请告知,马上删帖致歉。原文:http://wsfdl.com/devops/2016/09/27/%E7%89%88%E6%9C%AC%E5%8F%B7.html#首先看看某些常见软件的版本号:LinuxKernel:0.0.1,1.0.0,2.6.32,3.0.18…,若用X.Y.Z表示,则偶数Y表示稳定版本,奇数Y表示开发版本。Windo

    2025年10月25日
    7

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号