ArrayList的扩容机制详解,解决面试难题!

前言

大家好,我是chowley,不知各位在面试中,是否被问过 ‘读没读过相关框架的源码?’ 这个经典问题?我最近就遇到了,虽然我之前读过,但这玩意干读不进味啊

今天我就来讲讲ArrayList,这个白家长谈的经典数据结构的扩容机制!

ArrayList

在Java的集合框架中,ArrayList是一个非常常用的动态数组实现。了解其内部扩容机制对于我们编写的代码十分有益。

1. 介绍

ArrayListjava.util包下的一个类,它实现了动态数组的数据结构。相比于传统数组,ArrayList具有自动扩容的特性,可以根据需要动态地调整数组的大小。

2. 扩容机制

ArrayList的元素数量接近或超过其当前容量时,就会触发扩容操作。ArrayList的扩容机制主要涉及以下几个关键参数:

  • elementData: 用于存储实际元素的数组。
  • size: 当前ArrayList中元素的个数。
  • DEFAULT_CAPACITY: 默认初始容量,一般为10。
  • MAX_ARRAY_SIZE: 数组的最大容量,一般为Integer.MAX_VALUE - 8

2.1 扩容触发条件

扩容会在以下两种情况下触发:

  1. 添加元素时,size超过elementData的长度

  2. 使用带有指定初始容量的构造方法,并且该初始容量大于默认容量,也会触发扩容。

2.2 扩容操作过程

扩容的核心方法是 grow(int minCapacity)。下面是扩容的大致过程:

  1. 计算新容量:
    新容量一般为原容量的 1.5 倍,即 oldCapacity + (oldCapacity >> 1)。如果这个值仍然不足以容纳 minCapacity 个元素,那么新容量将被设置为 minCapacity

  2. 检查是否超过最大容量:

    如果新容量超过了 MAX_ARRAY_SIZE,则新容量将被设置为 Integer.MAX_VALUE。这是由于数组的最大长度是 Integer.MAX_VALUE
  3. 创建新数组并复制元素:

    利用 Arrays.copyOf 创建一个新的数组,并将原数组中的元素复制到新数组中。
  4. 替换原数组:

    elementData 指向新的数组。

2.3 扩容示例代码

以下是 ArrayList 扩容机制的示例代码:

private void grow(int minCapacity) {// 获取原容量int oldCapacity = elementData.length;// 计算新容量int newCapacity = oldCapacity + (oldCapacity >> 1);// 检查是否足够容纳minCapacity个元素if (newCapacity - minCapacity < 0)newCapacity = minCapacity;// 检查是否超过最大容量if (newCapacity - MAX_ARRAY_SIZE > 0)newCapacity = hugeCapacity(minCapacity);// 创建新数组并复制元素elementData = Arrays.copyOf(elementData, newCapacity);
}private static int hugeCapacity(int minCapacity) {if (minCapacity < 0) // 溢出throw new OutOfMemoryError();return (minCapacity > MAX_ARRAY_SIZE) ?Integer.MAX_VALUE :MAX_ARRAY_SIZE;
}

总结

了解ArrayList的扩容机制是编写高性能Java代码的重要一环。通过深入了解其内部实现,我们能够更好地利用这一数据结构,避免不必要的扩容操作,提高程序的效率。

希望通过本文的介绍,大家能够对ArrayList的扩容机制有一个清晰而深入的理解~

好了,以上就是本文的全部内容,如有问题欢迎留言讨论。

我是chowley,一个专注互联网技术和软件质量保障领域的博主,我们下次再见!

欢迎点赞、评论、收藏,it's important for me.

欢迎点赞、评论、收藏,it's important for me.

欢迎点赞、评论、收藏,it's important for me.

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/661806.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

揭秘远程控制APP的便捷之美!

在这个科技日新月异的时代&#xff0c;我们的生活被各种手机软件所包围。几乎每个人都有一个甚至多个手机&#xff0c;你是否也有遇到过需要远程操作自己某一台手机的场景呢&#xff1f;今天&#xff0c;我要向大家推荐一款神奇的手机远程操作神器&#xff0c;让你可以随时随地…

Kore.ai获10亿元融资,提供定制化类ChatGPT助手

1月31日&#xff0c;生成式AI和企业对话平台Kore.ai在官网宣布&#xff0c;获得1.5 亿美元&#xff08;约10.7亿元&#xff09;融资。本次由FTV Capital 领投&#xff0c;英伟达等跟投。 Kore.ai主要提供银行、医疗、零售、营销、人力资源等多种领域的&#xff0c;定制化类Cha…

【动态规划】【C++算法】1340. 跳跃游戏 V

作者推荐 【动态规划】【字符串】【表达式】2019. 解出数学表达式的学生分数 本文涉及知识点 动态规划汇总 LeetCode1340跳跃游戏 V 给你一个整数数组 arr 和一个整数 d 。每一步你可以从下标 i 跳到&#xff1a; i x &#xff0c;其中 i x < arr.length 且 0 < x…

zsh: command not found: mysql (mac通过安装MySQL后终端cmd找不到mysql命令)

考虑是mysql环境变量没有配置的问题 1.查找mysql安装路径 ps -ef|grep mysql 2.先启动上安装的mysql 3. 查看 .bash_profile 文件 ls -al 查看是否有(.bash_profile)文件 如果没有就输入以下命令创建一个&#xff0c;再查看 touch .bash_profile 4.打开 .bash_profile 文件 …

C++——析构函数

C——析构函数 什么是析构函数 析构函数是C中的一个特殊的成员函数&#xff0c;它在对象生命周期结束时被自动调用&#xff0c;用于执行对象销毁前的清理工作。析构函数特别重要&#xff0c;尤其是在涉及动态分配的资源&#xff08;如内存、文件句柄、网络连接等&#xff09;…

Android 8.1 设置--声音中增加通话音量

Android 8.1 设置--声音中增加通话音量 近来收到项目需求&#xff0c;想要在设置--声音中增加一项通话音量调节&#xff0c;具体修改参照如下&#xff1a; /vendor/mediatek/proprietary/packages/apps/MtkSettings/res/values/strings.xml <!-- Sound: Title for the opt…

ARM/CM3/CM4:读写内核寄存器和内核特殊寄存器

方式1&#xff1a;内联汇编&#xff0c;所以跟C编译器有关&#xff0c;有些编译器可能会不支持&#xff08;每种编译器内联汇编的形式都不一样&#xff09;&#xff0c;本代码在MDK的“defaul compiler version 6”编译器里测试通过。 uint32_t core_res_c;void set_core_res(…

kubekey网页版安装k8s集群操作流程

kubekey可以一键拉起k8s集群并完成kubesphere的部署&#xff0c;以后kubekey简称kk。kk 3.2版本以前都是在宿主机上完成对应的创建集群、添加节点、升级等操作的&#xff0c;3.2版本后开始往页面操作的方向演进&#xff0c;kk 3.2版本现在还是alpha&#xff0c;所以不推荐在生产…

C语言数组:从入门到进阶

前言&#xff1a; 在这篇博客中&#xff0c;我们将学习如何使用C语言数组的基本知识。数组是C语言中的一种重要数据结构&#xff0c;它允许我们存储一系列相同类型的数据。我们将讨论数组的定义、初始化、访问元素、遍历数组以及数组的应用场景。此外&#xff0c;我们还将通过…

MySQL基础查询篇(1)-使用GROUP BY分组数据

在MySQL数据库中&#xff0c;GROUP BY语句是一种用于分组数据的非常有用的功能。它允许我们根据指定的列将数据行分组为不同的集合&#xff0c;并对每个组应用聚合函数。这使得我们能够从大量数据中提取所需的汇总信息。 首先&#xff0c;让我们看一个简单的示例。假设我们有一…

SpringBoot使用Rabbit详解含完整代码

1. 摘要 本文将详细介绍如何在Spring Boot应用程序中集成和使用RabbitMQ消息队列。RabbitMQ是一个开源的消息代理和队列服务器&#xff0c;用于通过轻量级和可靠的消息在应用程序或系统之间进行异步通信。本文将通过步骤说明、代码示例和详细注释&#xff0c;指导读者在Spring…

【数据分享】1929-2023年全球站点的逐年最高气温数据(Shp\Excel\免费获取)

气象数据是在各项研究中都经常使用的数据&#xff0c;气象指标包括气温、风速、降水、湿度等指标&#xff0c;其中又以气温指标最为常用&#xff01;说到气温数据&#xff0c;最详细的气温数据是具体到气象监测站点的气温数据&#xff01; 之前我们分享过1929-2023年全球气象站…

python如何实现异步并发

下面是一个示例代码&#xff0c;展示了如何设计一个异步线程池&#xff0c;并实现线程池满了就等待&#xff0c;空了就继续扔的功能&#xff1a; import concurrent.futures import time # 创建一个线程池 thread_pool concurrent.futures.ThreadPoolExecutor(max_workers8) …

Oracle 如何强制重构索引

在Oracle数据库中&#xff0c;当索引变得碎片化或性能下降时&#xff0c;通常建议对索引进行重构。重构索引可以消除碎片&#xff0c;提高查询性能&#xff0c;并维护索引的完整性。在Oracle中&#xff0c;你可以使用ALTER INDEX语句来强制重构索引。 下面是强制重构索引的一般…

el-table动态合并

废话就不多说了&#xff0c;直接上代码&#xff01;&#xff01;&#xff01; 合并行 // 方法一 <template><div class"container"><el-table :data"dataSource" :border"true":header-cell-style"{ font-weight: normal,…

Kotlin中的内置函数-apply、let

在使用Kotlin的过程中会经常用到其内置函数&#xff0c;包括apply&#xff0c;let&#xff0c;run&#xff0c;with&#xff0c;also&#xff0c;takeIf,takeUnless函数等&#xff0c;想要更好熟悉Kotlin&#xff0c;这些函数必须烂熟于心&#xff0c;接下来让我们来逐步了解&a…

redis的AOF

redis 提供了两种持久化方式—— RDB(Redis DataBase) 和 AOF(Append Only File) &#xff0c;可以将 Redis 在内存中的数据库状态保存到磁盘里。 RDB快照并不是很可靠。如果服务器突然宕机了&#xff0c;最新的数据就会丢失。除了 RDB 持久化功能之外&#xff0c;Redis 还提供…

大语言模型之LlaMA系列- LlaMA 2及LLaMA2_chat(上)

LlaMA 2是一个经过预训练与微调的基于自回归的transformer的LLMs&#xff0c;参数从7B至70B。同期推出的Llama 2-Chat是Llama 2专门为对话领域微调的模型。 在许多开放的基准测试中Llama 2-Chat优于其他开源的聊天模型&#xff0c;此外Llama 2-Chat还做了可用性与安全性评估。 …

Docker应用之Nginx安装(二)

目录 一、拉取nginx镜像二、在宿主机中创建挂载目录三、将配置文件放到挂载目录四、创建容器并启动 五、总结 一、拉取nginx镜像 docker pull nginx 二、在宿主机中创建挂载目录 mkdir -p /data/nginx/{conf,conf.d,html,log} 三、将配置文件放到挂载目录 在/data/nginx/…

阅读笔记7:Molecular mechanisms of ovulation: co-ordination through the CC

Molecular mechanisms of ovulation: co-ordination through the cumulus complex 作者:Darryl L. Russell, Rebecca L. Robker 发表期刊:Human Reproduction Update 发表时间:22 January 2007 排卵的分子机制:通过卵丘复合体的协调 摘要部分 研究背景:成功的排卵需要在适…