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)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • jvm垃圾回收算法有哪些_java垃圾回收算法几种

    jvm垃圾回收算法有哪些_java垃圾回收算法几种在说垃圾回收算法之前,先谈谈JVM怎样确定哪些对象是“垃圾”。1.引用计数器算法:引用计数器算法是给每个对象设置一个计数器,当有地方引用这个对象的时候,计数器+1,当引用失效的时候,计数器-1,当计数器为0的时候,JVM就认为对象不再被使用,是“垃圾”了。引用计数器实

    2022年10月29日
  • 网络传真和传真服务器[通俗易懂]

    网络传真和传真服务器[通俗易懂]传真机自1906年在德国推出以来,到今天已走过一百多年的历史,传真的形式也从最早的机械传真、光电传真、数字传真发展到今天的电子传真、电脑传真、网络传真、无纸传真、传真系统、传真服务器、传真软件、传真卡等。   所谓电子传真机(包括各种类型的网络传真机、电脑传真机、数码传真机、无纸传真机、传真软件、传真系统、传真服务器等,下同),就是通过电脑收发传真。     在发送传真前,自动检

    2022年6月28日
  • java生成license_使用truelicense实现用于JAVA工程license机制(包括license生成和验证)…

    java生成license_使用truelicense实现用于JAVA工程license机制(包括license生成和验证)…开发的软件产品在交付使用的时候,往往会授权一段时间的试用期,这个时候license就派上用场了。不同于在代码中直接加上时间约束,需要重新授权的时候使用license可以避免修改源码,改动部署,授权方直接生成一个新的license发送给使用方替换掉原来的license文件即可。下面将讲述使用truelicense来实现license的生成和使用。Truelicense是一个开源的证书管理引擎,详细介…

    2022年7月26日
  • 谈谈.Net技术面试【转】

    谈谈.Net技术面试【转】

    2021年8月15日
  • Jenkins安装_jenkins sonar

    Jenkins安装_jenkins sonar前言jenkins的环境搭建方法有很多,本篇使用docker快速搭建一个jenkins环境。环境准备:mac/Linuxdockerdocker拉去jenkins镜像先下载jenkins镜

    2022年7月29日
  • Kafka学习之一 Kafka是什么,主要应用在什么场景?

    Kafka学习之一 Kafka是什么,主要应用在什么场景?Kafka是什么,主要应用在什么场景,能为我们解决什么问题

    2022年10月13日

发表回复

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

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