当前位置: 首页 > news >正文

ArrayList源码学习

1. ArrayList参数及其含义

  1. 存储对象元素
transientObject[]elementData;
  1. 元素的个数
privateintsize;

2. 常用方法

  1. get()方法
publicEget(intindex){rangeCheck(index);returnelementData(index);}

get方法传一个index参数,表示获取指定下标的元素。get方法内首先进行rangCheck范围检查。然后返回下标对应的元素。

privatevoidrangeCheck(intindex){if(index>=size)thrownewIndexOutOfBoundsException(outOfBoundsMsg(index));}

rangCheck判断要获取的数据索引是否大于等于arrayList的长度。大于等于就抛异常。

EelementData(intindex){return(E)elementData[index];}

从数组中获取元素并转换为指定类型返回。
2. set方法

publicEset(intindex,Eelement){rangeCheck(index);EoldValue=elementData(index);elementData[index]=element;returnoldValue;}

set方法首先校验要修改的元素位置(校验同上),如果校验通过,访问数组中下标对应的元素,然后修改他的值,并返回修改前的值
3. add方法

publicbooleanadd(Ee){ensureCapacityInternal(size+1);// Increments modCount!!elementData[size++]=e;returntrue;}

ensureCapacityInternal(size + 1);第一行确保元素个数不会超过数组长度。
elementData[size++] = e;在末尾添加元素,并且修改size的大小。

privatevoidensureCapacityInternal(intminCapacity){ensureExplicitCapacity(calculateCapacity(elementData,minCapacity));}

ensureCapacityInternal方法首先调用calculateCapacity计算容量。然后调用ensureExplicitCapacity确保数组长度可以容纳下这么多的元素。

privatevoidensureExplicitCapacity(intminCapacity){modCount++;// overflow-conscious codeif(minCapacity-elementData.length>0)grow(minCapacity);}

minCapacity - elementData.length > 0数组中元素个数大于数组长度。需要扩容,调用grow方法进行扩容。

privatevoidgrow(intminCapacity){// overflow-conscious codeintoldCapacity=elementData.length;intnewCapacity=oldCapacity+(oldCapacity>>1);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);}

扩容后新的数组容量为旧数组容量的1.5倍oldCapacity + (oldCapacity >> 1)。如果扩容后的数组容量减去元素个数大于0,说明扩容不够。让新的数组容量等于元素个数。
if (newCapacity - MAX_ARRAY_SIZE > 0)然后判断新的数组容量是否大于最大的数组大小,大于的话需要调用hugeCapacity获取最大的数组长度。

Arrays.copyOf(elementData, newCapacity);将旧的数组复制到新的数组中,新数组的容量为上面计算所得。

  1. indexOf方法
publicintindexOf(Objecto){if(o==null){for(inti=0;i<size;i++)if(elementData[i]==null)returni;}else{for(inti=0;i<size;i++)if(o.equals(elementData[i]))returni;}return-1;}

根据查找的元素分了两种情况。一种要查的元素为空,遍历数组找到为空的元素返回下标。一种要查的元素不为空,遍历数组,找到相同的元素返回下标。否则返回-1。

  1. remove方法
publicbooleanremove(Objecto){if(o==null){for(intindex=0;index<size;index++)if(elementData[index]==null){fastRemove(index);returntrue;}}else{for(intindex=0;index<size;index++)if(o.equals(elementData[index])){fastRemove(index);returntrue;}}returnfalse;}

根据要删除的元素分了两种情况,一种是删除空元素,一种是非空元素。
对于空元素:遍历数组,如果元素为空,调用fastRemove进行元素的删除。
对于非空元素:遍历数组,如果元素与要删除的元素相同,调用fastRemove方法删除元素。
删除成功返回true,否则返回false。

privatevoidfastRemove(intindex){modCount++;intnumMoved=size-index-1;if(numMoved>0)System.arraycopy(elementData,index+1,elementData,index,numMoved);elementData[--size]=null;// clear to let GC do its work}

int numMoved = size - index - 1;首先计算要移动的元素个数。要移动的元素个数为要删除元素之后的所有元素,不包括被删除元素。
如果要删除的元素大于0,则调用System.arraycopy方法进行数据的移动,对于源数组和目标数组相同的情况,该方法会首先将index+1到index+1+numMoved(结果为数组结尾,比如对于下标为0,1,2,3的数组,删除下标为1的元素,该处计算后的值为1+1~1+1+2)的值复制到一个临时数组,然后将临时数组的值复制到index到index+numMoved的位置。
elementData[--size] = null;将最后一个元素赋值为空,同时修改元素个数为size-1。

http://www.jsqmd.com/news/484278/

相关文章:

  • 点云处理新姿势:手把手教你用Stacked VFE实现高效特征编码(附代码示例)
  • 基于STM32与滑模观测器的无感FOC算法工程实践
  • PyInstaller打包PaddleOCR项目实战:如何让exe文件真正离线运行
  • PODAAC数据下载器的高级用法:如何利用命令行参数精准获取地球科学数据
  • 机器学习毕设选题避坑指南:从技术可行性到工程落地的完整评估框架
  • OpenStack Yoga版实战:用Skyline Dashboard替换Horizon面板的完整避坑指南
  • IndexTTS 2.0新手常见问题解答:从音频准备到情感调节全解析
  • Unity 2D游戏开发:如何用Collider2D实现完美的平台跳跃碰撞检测
  • 6. TI F28P550 DSP定时器配置实战:基于SysConfig实现1秒LED精准闪烁
  • 手把手教你用iperf3测量投屏卡顿原因:WiFi UDP丢包率与延时测试实战
  • Qwen-Image-Edit容器化部署指南:Docker实战
  • TQVaultAE:解放泰坦之旅玩家的装备管理革命
  • asp公司职员管理系统xns论文
  • 零基础搭建数字人客服:lite-avatar形象库实战教程
  • OWL ADVENTURE赋能.NET应用:C#调用视觉AI模型全流程
  • 立创三相双向SiC无桥图腾柱逆变器-PFC开发板:硬件设计、调试与软件配置全解析
  • Llama-3.2V-11B-cot多场景:支持教育答题、医疗解读、工业质检、法律分析四大方向
  • Verilog状态机实战:从零搭建交通灯控制系统(附完整代码)
  • Llama-3.2V-11B-cot教程:支持多语言图文输入的跨文化推理能力验证
  • 功率半导体器件核心公式的工程解读
  • SpringSecurity5.x实战:从零配置JWT认证与RBAC权限控制(附完整代码)
  • Yi-Coder-1.5B在数据结构教学中的应用案例
  • Janus-Pro-7B惊艳效果:方言手写笔记→OCR识别→普通话转写+要点提炼
  • 数据可视化实战 | Tableau数据建模与预处理技巧全解析
  • 贝叶斯公式不头疼:用‘结果反推原因‘的思维搞定条件概率难题
  • AUTOSAR开发实战:如何在Davinci Developer中高效配置ADT与IDT映射(附避坑指南)
  • 用ggplot2给单细胞UMAP图加等高线:手把手教你美化FeaturePlot密度图
  • UNETR深度解析:Transformer如何重塑三维医学影像分割的格局
  • Vector VT_CSM模块配置全攻略:从选型到DBC文件生成
  • Zotero翻译插件避坑指南:为什么你的PDF Translate总报错?6个常见问题解决方法