位置: IT常识 - 正文

1、ArrayList源码解析(arraylist源码分析1.8)

编辑:rootadmin
1 概述 ArrayList实现了List接口,是 顺序容器,允许放入null元素 有一个容量(capacity),表示底层数组的实际大小。如果容量不足,容器会 自动增大底层数组的大小 支持泛型,泛型擦除后,容器的元素都是 Object类型 ArrayList没有实现同步(synchronized) ... 目录1 概述2 底层数据结构3 构造函数4 自动扩容5 set() get() remove()6 Fail-Fast机制1 概述ArrayList实现了List接口,是 顺序容器,允许放入null元素有一个容量(capacity),表示底层数组的实际大小。如果容量不足,容器会 自动增大底层数组的大小支持泛型,泛型擦除后,容器的元素都是 Object类型ArrayList没有实现同步(synchronized),因此它是 线程不安全的。(vector线程安全)关于数组:一旦数组初始化完成,则长度不可改变 因此ArrayList扩容时会涉及数组的拷贝 2 底层数据结构

推荐整理分享1、ArrayList源码解析(arraylist源码分析1.8),希望有所帮助,仅作参考,欢迎阅读内容。

文章相关热门搜索词:arraylist1.8,arrays.sort()源码,arraylist源码分析1.8,arrays.sort()源码,array.sort源码,arraylist源码分析1.8,arraylist源码分析1.8,arraylist 源码,内容如对您有帮助,希望把文章链接给更多的朋友!

两个重要成员变量

Object[] elementData:

存储列表元素的数组;该数组的长度就是列表的容量列表的容量是指它所能存储元素的最大个数

size:1、ArrayList源码解析(arraylist源码分析1.8)

列表的大小。指当前列表包含的元素个数,跟容量不是一个概念

size 跟 elementData数组长度是不一样的。elementData 允许长度大于元素的个数

transient Object[] elementData; //存储列表元素的数组 private int size;//元素的数量 protected transient int modCount = 0; //list的修改次数3 构造函数

有三个构造函数:

指定初始容量大小时,创建一个容量为参数的Object数组,并赋值给数据数组不指定初始容量大小时,数据数组赋值为一个无限容量的空数组构造参数为集合类型,将参数转换成Object类型数组,并赋值给数据数组注意,只有当第一次add元素时,才会指定数组的长度

参照源码:

//指定初始容量大小时,创建一个容量为参数的Object数组,并赋值给数据数组 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); } }// 不指定初始容量大小时,数据数组赋值为一个无限容量的空数组 public ArrayList() { this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA; }// 构造参数为集合类型,将参数转换成Object类型数组,并赋值给数据数组 public ArrayList(Collection<? extends E> c) { elementData = c.toArray(); if ((size = elementData.length) != 0) { // c.toArray might (incorrectly) not return Object[] (see 6260652) if (elementData.getClass() != Object[].class) elementData = Arrays.copyOf(elementData, size, Object[].class); } else { // replace with empty array. this.elementData = EMPTY_ELEMENTDATA; } }4 自动扩容添加元素时,会判断添加后是否超出当前数组长度,超出则会执行数组扩容;数组扩容时,会将老数组中的元素重新 拷贝一份到新的数组中。(因为数组长度不可变,因此需要创建新数组)数组执行扩容,扩容后的容量为扩容前的 1.5倍尽可能评估所需要容量的大小,避免扩容。(因为扩容占用更多的内存)

参考源码:

重点!!!!!:添加前,都判断是否需要扩容:(如果size+1后,超过elementData的长度,则执行扩容,扩容为原来的1.5倍)

public boolean add(E e) { ensureCapacityInternal(size + 1); // size 初始化时是0, elementData[size++] = e; return true;}private void ensureCapacityInternal(int minCapacity) { ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));}//计算所需容量:第一次添加时,容量为10;反则,容量为当前长度+1private static int calculateCapacity(Object[] elementData, int minCapacity) { if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) { return Math.max(DEFAULT_CAPACITY, minCapacity);//DEFAULT_CAPACITY = 10,即第一次添加时,数组长度变为10 } return minCapacity;//如果数组不为空时,最小长度是当前长度+1}//再次计算数组所需容量private void ensureExplicitCapacity(int minCapacity) { modCount++;//列表修改次数递增 //所需容量大于数组的长度,则执行扩容 if (minCapacity - elementData.length > 0) grow(minCapacity);}//扩容,数组的内存状态已经发生变化了private void grow(int minCapacity) { int oldCapacity = elementData.length; int newCapacity = oldCapacity + (oldCapacity >> 1);// 新的长度为旧长度的1.5倍 【右移1位(除以2)】 if (newCapacity - minCapacity < 0) // 如果扩容后的长度小于所需要的最小长度,则使用最小长度(基本不会发生) newCapacity = minCapacity; if (newCapacity - MAX_ARRAY_SIZE > 0) //这里是极限的情况,即逼近数组分配的最大内存空间 newCapacity = hugeCapacity(minCapacity); elementData = Arrays.copyOf(elementData, newCapacity); // 执行数组拷贝}5 set() get() remove()set()方法也就变得非常简单,直接对数组的指定位置赋值即可。public E set(int index, E element) { rangeCheck(index);//下标越界检查 E oldValue = elementData(index); elementData[index] = element;//赋值到指定位置,复制的仅仅是引用 return oldValue;//返回原先位置上的元素}get()方法同样很简单,唯一要注意的是由于底层数组是Object[],得到元素后需要进行类型转换。public E get(int index) { rangeCheck(index); return (E) elementData[index];//注意类型转换}remove()方法也有两个版本,一个是remove(int index)删除指定位置的元素,另一个是remove(Object o)删除第一个满足o.equals(elementData[index])的元素。删除操作是add()操作的逆过程,需要将删除点之后的元素向前移动一个位置。需要注意的是为了让GC起作用,必须显式的为最后一个位置赋null值。public E remove(int index) { rangeCheck(index); modCount++; E oldValue = elementData(index); int numMoved = size - index - 1; if (numMoved > 0) System.arraycopy(elementData, index+1, elementData, index, numMoved); elementData[--size] = null; //清除该位置的引用,让GC起作用 return oldValue;}6 Fail-Fast机制

ArrayList也采用了快速失败的机制,通过记录 modCount 参数来实现。在面对并发的修改时,迭代器很快就会完全失败,而不是冒着在将来某个不确定时间发生任意不确定行为的风险。

本文链接地址:https://www.jiuchutong.com/zhishi/310262.html 转载请保留说明!

上一篇:ps魔棒中的容差是什么意思(ps魔棒工具选择图像时在容差数值较大的是)

下一篇:织梦dedecms整合阿里云oss支持ckeditor|kindeditor|ueditor支持图集(织梦cms要钱吗)

  • 央视频上线时间(央视频app什么时候上线的)

    央视频上线时间(央视频app什么时候上线的)

  • 美团支付详情可以删除吗(美团支付详情在哪里)

    美团支付详情可以删除吗(美团支付详情在哪里)

  • 手机淘宝未发货订单怎么申请退款(手机淘宝未发货怎么退款)

    手机淘宝未发货订单怎么申请退款(手机淘宝未发货怎么退款)

  • 双引号怎么打在电脑上(双引号怎么打在田字格中例子)

    双引号怎么打在电脑上(双引号怎么打在田字格中例子)

  • 抖音怎么设置评论隐私(抖音怎么设置评论别人看不到)

    抖音怎么设置评论隐私(抖音怎么设置评论别人看不到)

  • 手机屏幕比例(手机屏幕比例修改器无root)

    手机屏幕比例(手机屏幕比例修改器无root)

  • 苹果数据线一定要用原装的吗(苹果数据线一定要买原装的吗)

    苹果数据线一定要用原装的吗(苹果数据线一定要买原装的吗)

  • 手机充电器能给笔记本电脑充电吗(手机充电器能给蓝牙耳机充电吗)

    手机充电器能给笔记本电脑充电吗(手机充电器能给蓝牙耳机充电吗)

  • qq点赞怎么不显示(qq点赞怎么不显示消息)

    qq点赞怎么不显示(qq点赞怎么不显示消息)

  • 京东如何查看确认收货的时间(京东上面怎么查询订单到哪了)

    京东如何查看确认收货的时间(京东上面怎么查询订单到哪了)

  • 算法的两个基本要素(算法的两个基本原则)

    算法的两个基本要素(算法的两个基本原则)

  • GLK_AL00华为什么型号(华为glk_al00手机)

    GLK_AL00华为什么型号(华为glk_al00手机)

  • 苹果11pro max怎样关机(苹果11pro max怎样关机开机)

    苹果11pro max怎样关机(苹果11pro max怎样关机开机)

  • 宽带自带wifi吗(宽带有wifi吗)

    宽带自带wifi吗(宽带有wifi吗)

  • ETC扫描不了怎么回事(etc扫描没反应)

    ETC扫描不了怎么回事(etc扫描没反应)

  • ipad充电需要充满吗(iPad充电需要充到100%吗)

    ipad充电需要充满吗(iPad充电需要充到100%吗)

  • 锤子手机如何导出照片(锤子手机资料怎么传到华为手机)

    锤子手机如何导出照片(锤子手机资料怎么传到华为手机)

  • 数据中心是指什么(数据中心是指什么意思)

    数据中心是指什么(数据中心是指什么意思)

  • 手机开启sos怎么关闭(手机sos功能怎么启用)

    手机开启sos怎么关闭(手机sos功能怎么启用)

  • 快手关注上限怎么解除(快手关注上限怎么取消)

    快手关注上限怎么解除(快手关注上限怎么取消)

  • pholzps是什么牌子(phlllps什么品牌)

    pholzps是什么牌子(phlllps什么品牌)

  • Mac怎么设置输入法切换快捷键?Mac设置输入法切换快捷键方法(macbook怎么设置输入法)

    Mac怎么设置输入法切换快捷键?Mac设置输入法切换快捷键方法(macbook怎么设置输入法)

  • vue2配置cesium详细教程(vue2 mixin)

    vue2配置cesium详细教程(vue2 mixin)

  • tsar命令  收集服务器系统信息

    tsar命令 收集服务器系统信息

  • 财务软件怎么样从捷软系统导出数据
  • 老板故意拖欠税款怎么办
  • 管理部门社保入哪个科目
  • 残疾人就业保障金征收使用管理办法
  • 房地产会计预收账款明细科目
  • 终止合同后原合同怎么处理
  • 企业开办费用的预算
  • 冬虫夏草开票什么税率
  • 怎么进行利润招财
  • 印花税记到哪个会计科目
  • 增值税勾选平台在哪里
  • 进口增值税计入关税完税价格吗
  • 母公司向全资子公司划转土地
  • 现金流量的具体识别标准
  • 购买的固定资产进项税可以抵扣吗
  • 独立账户负债核算内容
  • 溢价购入债权投资是为啥
  • 国家信用信息公司系公示
  • php7.3
  • windows 11任务栏没有网络图标
  • PHP:get_meta_tags()的用法_url函数
  • 递延所得税资产是什么意思
  • 房贷贷款利息计算
  • 企业委托境外研发所发生的费用
  • windows11 beta渠道
  • element ui+vue
  • excel多表操作法
  • 二次规划是什么意思
  • tim模块
  • php实现日历
  • 地税没申报罚款多少
  • Yii2如何批量添加数据
  • php实现购物车功能
  • cobit框架
  • linux中web服务器的安装,配置与测试
  • 猿类作文
  • 仓库发货打包以及建议年终总结
  • 免费赠送的产品报关金额
  • 应付账款转入营业外收入会计分录
  • 其它应付款核算项目
  • wordpress部署到github
  • Discus X 3 门户改造熊掌号网页教程
  • 新公司筹建期要做账吗
  • 小规模免税怎么做账务处理
  • 公司购买基金入什么科目
  • 公司的资金管理模式是什么?
  • 分公司员工在总公司缴纳社保
  • 跨年收入退款如何处理
  • 开具发票要注意的方面是有哪些?
  • 进仓费开票是几个点
  • 运输公司内账会计每天需要做什么
  • 建筑企业的安全生产许可证由谁颁发
  • 异地预缴税款怎么抵扣
  • 行政事业单位过节费发放规定
  • 外资企业股权转让给内资企业流程
  • 期初借款余额计算公式
  • 收入与费用配比也就是费用要由收入补偿
  • 公司被冻结
  • 公司成本核算流程
  • sql语句查询记录
  • .NET Framework SQL Server 数据提供程序连接池
  • mssqlserveradhelper
  • Ubuntu安装ssh
  • 如何设置windows启动密码
  • mac vlc
  • 在linux中使用v2ray
  • win7旗舰版系统激活密钥
  • javascript中对象一般由什么组成
  • node.js使用教程
  • cocoscreator lua
  • jquery 滑块
  • wmic命令详解
  • node.js的express
  • python数字类型及操作
  • 辽宁省耕地占用税税率
  • 我国烟草税的税点是多少
  • 江苏地税每月社保多少钱
  • 吉林省国税局网站官网
  • 国税和地税的税种有哪些
  • 临汾的公司需要交社保吗
  • 免责声明:网站部分图片文字素材来源于网络,如有侵权,请及时告知,我们会第一时间删除,谢谢! 邮箱:opceo@qq.com

    鄂ICP备2023003026号

    网站地图: 企业信息 工商信息 财税知识 网络常识 编程技术

    友情链接: 武汉网站建设