集合框架图:

集合和数组的区别


AarrayList

ArrayList底层实现原理

ArrayList的底层实现是基于数组的动态扩容。

  1. 初始容量:当创建一个新的ArrayList对象时,它会分配一个初始容量为10的数组。这个初始容量可以根据需求进行调整。
//表示默认的初始容量,该值被设置为10
private static final int DEFAULT_CAPACITY = 10;
//表示一个空数组,即一个长度为0的Object数组。
private static final Object[] EMPTY_ELEMENTDATA = {};
//表示具有默认初始容量的空数组。在无参构造函数中使用这个数组。
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
//该数组用于存储ArrayList的元素。它是ArrayList的核心数据结构。transient Object[] elementData;
//表示ArrayList当前包含的元素数量。private int size;
//构造一个具有指定初始容量的ArrayList。如果指定的初始容量大于0,将创建一个具有此大小的新数组;如果初始容量为0,则使用空数组EMPTY_ELEMENTDATA;否则,抛出IllegalArgumentException异常。public ArrayList(int initialCapacity) {if (initialCapacity > 0) {this.elementData = new Object[initialCapacity];} else if (initialCapacity == 0) {this.elementData = EMPTY_ELEMENTDATA;} else {throw new IllegalArgumentException("Illegal Capacity: "+initialCapacity);}}
//构造一个默认初始容量的ArrayList。使用数组DEFAULTCAPACITY_EMPTY_ELEMENTDATA作为初始数组。public ArrayList() {this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;}
  1. 添加元素:当使用ArrayList的add(E element)方法添加一个元素时,它会先检查数组是否已满。如果数组已满,ArrayList会执行以下操作:
  1. 创建一个新的容量更大的数组,默认情况下是原数组容量的1.5倍(在Java 7之前是原数组容量的两倍)。例如,如果原数组的容量是10,那么新数组的容量将是15。
  2. 将原数组中的元素复制到新数组中。
  3. 更新ArrayList的内部数组引用为新数组。
  4. 更新ArrayList的内部数组引用为新数组。
 private void grow(int minCapacity) {//获取当前 ArrayList 的容量int oldCapacity = elementData.length;//计算新的容量,即将原始容量的一半加到原始容量上,相当于扩容 50%。int newCapacity = oldCapacity + (oldCapacity >> 1);//检查新容量是否小于所需的最小容量,如果是则将最小容量设为新容量。这个检查主要用于确保扩容后的容量足以容纳要添加的元素。if (newCapacity - minCapacity < 0)newCapacity = minCapacity;//检查新容量是否超过了 MAX_ARRAY_SIZE,如果是则调用 hugeCapacity(minCapacity) 方法获取一个巨大容量。MAX_ARRAY_SIZE 是 Java 数组的最大容量限制。if (newCapacity - MAX_ARRAY_SIZE > 0)newCapacity = hugeCapacity(minCapacity);//将 elementData 数组扩容为新的容量。利用 Arrays.copyOf() 方法可以方便地将数组扩容并复制原始元素到新数组中。elementData = Arrays.copyOf(elementData, newCapacity);}
  1. 删除元素:当使用ArrayList的remove(int index)方法删除一个元素时,ArrayList会执行以下操作:
  1. 将要删除的元素之后的所有元素向前移动一个位置,以覆盖被删除的元素。
  2. 更新ArrayList的内部数组长度。

public E remove(int index) {//校验索引是否越界,如果索引值小于0或者大于等于当前列表的大小 size,则抛出 IndexOutOfBoundsException 异常。rangeCheck(index);
//(用于记录结构性修改次数的计数器)加1,表示对 ArrayList 进行了一次修改。modCount++;//调用 elementData(index) 方法获取要删除的元素的值,将其保存为 oldValue。E oldValue = elementData(index);
//计算需要移动的元素的个数,即从待删除元素的下一个位置到列表末尾的元素个数。int numMoved = size - index - 1;//检查是否需要移动元素。如果 numMoved 大于 0,表示待删除的元素不是列表的最后一个元素,需要将后面的元素往前移动,以填补删除元素的空缺。if (numMoved > 0)//使用 System.arraycopy() 方法将后面的元素往前移动。从 elementData 数组的 index+1 位置开始,复制 numMoved 个元素到 elementData 数组的 index 位置,覆盖待删除元素。System.arraycopy(elementData, index+1, elementData, index,numMoved);//将列表中最后一个位置的元素设置为 null,以便让垃圾回收机制回收。同时,将列表的大小 size 减1,相当于删除了一个元素。elementData[--size] = null;
//返回被删除的元素return oldValue;}
  1. 获取元素:当使用ArrayList的get(int index)方法获取一个元素时,ArrayList会直接通过索引访问数组中的对应元素。
    E elementData(int index) {return (E) elementData[index];}
  1. 内存管理:当ArrayList执行扩容或缩容操作时,它会分配新的内存来存储更大或更小的数组,然后将旧数组中的元素复制到新数组中。这意味着在扩容或缩容过程中会涉及到内存的分配和复制操作,可能会带来一定的性能开销。

2023年7月14日,ArrayList底层相关推荐

  1. 全国计算机技术与软件专业技术资格(水平)考试报名时间 上半年2023年3月13日开始,下半年2023年8月14日开始

    根据2023年计算机技术与软件专业技术资格(水平)考试工作计划,可以得知,2023年软考报名时间--上半年2023年3月13日开始,下半年2023年8月14日开始. 全国各地报名入口: 全国各地报名入 ...

  2. 【软考备战·希赛网每日一练】2023年4月14日

    文章目录 一.今日成绩 二.错题总结 第一题 第二题 第三题 第四题 三.知识查缺 题目及解析来源:2023年04月14日软件设计师每日一练 一.今日成绩 二.错题总结 第一题 解析: 具有 最优子结 ...

  3. 2023年4月14日,open ai 还是能接收到短信验证码

    前言 从昨天开始,有不少网友加我微信,问的基本都是同一个问题,应该注册GPT账号的时候,应该都收到了如下的报错内容,主要是open ai 开始检测滥用问题了. 问题 一:The carrier ass ...

  4. 世界主要国家和城市经纬度(2023年3月14日整理)

    近日做驾驶舱,要用到各国主要城市经纬度数据,网上很多是付费的,注册下载很麻烦. 整理了一稿给大家免费试用. 资源链接:(4条消息) 世界国家主要城市经纬度(免费)-数据集文档类资源-CSDN文库

  5. 【每日随笔】2023年02月14日随笔 ( 随便写点 | 技术无关、没事别点进来看、好好学技术 | 如何攒钱 | 插管与拔管 | 返贫途径 | 守财 | 财富增长 | 推荐书籍 )

    文章目录 一.如何攒钱 二.插管与拔管 三.返贫途径 四.守财 五.财富增长 六.御民之术 七.推荐书籍 一.如何攒钱 如何攒钱 : 有钱存银行 , 只买 国债 > 大额存单 > 定期存款 ...

  6. 2023年7月14日~15日

    1:思维导图 3:有 1.2.3.4个数字,能组成多少互不相同且无重复的三位? 都是多少? 4:终端输入一个数,输出他的二进制(二进制输出不能使用格式符) 5:定义一个一维整形数组,使用for循环实现 ...

  7. 3月14日 | ICLR 2023预讲会深度学习领域顶会专场一

    点击蓝字 关注我们 AI TIME欢迎每一位AI爱好者的加入! 哔哩哔哩直播通道 扫码关注AI TIME哔哩哔哩官方账号预约直播 2023年3月14日 10:00-12:00  14:30-16:30 ...

  8. 闪光桐人の实习日记(2023年2月13-17日)

    文章目录 2023年2月17日 SpringBoot集成Redis redis存储结构介绍 存储结构 数据结构 高速读写快的原因 基础数据对象介绍 最基础单元数据结构SDS SDS的内存分配与释放 架 ...

  9. 陆金所通过聆讯:拟4月14日香港上市 两年蒸发超270亿美元

    雷递网 雷建平 4月11日 陆金所控股有限公司(简称:"陆金所")日前通过港交所上市聆讯,预计2023年4月14日在香港上市. 陆金所此次以介绍方式申请股票在港交所上市,不涉及新股 ...

最新文章

  1. 避免在JSP中写java代码
  2. 学会python爬虫怎么赚钱-自学python爬虫赚钱经历
  3. rust高级矿场_高级 Rust 所有权管理
  4. 产品经理必备的14大效率工具
  5. 发点去大唐芙蓉园的pp
  6. 云炬Android开发笔记 5-3,4Restful请求的处理
  7. PaddlePaddle, TensorFlow, MXNet, Caffe2 , PyTorch五大深度学习框架2017-10最新评测
  8. CefSharp向浏览器中指定DOM发送点击事件
  9. 解决MySQL不允许从远程访问的方法
  10. 扎金花 游戏开发细节与部分代码
  11. MySQL将一张表数据插入到另一张表
  12. java的demo打印功能_java实现打印功能demo
  13. 业余草 2018 技术文章合集整理,适合入门、中级、高级、架构师进阶
  14. 为Linux安装虚拟PDF打印机
  15. TypeError: ufunc ‘true_divide‘ output (typecode ‘d‘) could not be coerced to provided outp
  16. 光环python培训
  17. javascript atob()函数和 btoa()函数-Base64的编码与解码
  18. 【Latex】如何用 latex 分双栏(分两列)
  19. iVMS-4200 Vs区别_【5G科普】5G知识知多少?#之5G与4G的区别
  20. 考研英语词汇文章4-Freshman Year

热门文章

  1. linux testdisk使用教程,使用TestDisk恢复因安装Ubuntu导致的硬盘误格
  2. position样式属性
  3. 3D角色 毛发制作 成束修改器的使用
  4. 在Android C/C++层添加LOG调试(LOGI\LOGD\LOGE...)输出支持 [ZZ]
  5. HDU 4379 The More The Better [枚举]
  6. 理解Dilation convolution
  7. html之文本框的onkeydown()响应Enter键——键盘事件
  8. 视频会议将是未来即时通讯平台的主流
  9. ie的html缓存问题,解决IE下Ajax请求无效,IE请求缓存问题
  10. STM32系列——工程移植(从stm32f103c8t6工程到stm32f103zet6工程)