位置: 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要钱吗)

  • 小度音箱怎么连接网络(小度音箱怎么连接QQ音乐)

    小度音箱怎么连接网络(小度音箱怎么连接QQ音乐)

  • 朋友圈画质怎么设置高清(朋友圈画质怎么才能不被压缩视频)

    朋友圈画质怎么设置高清(朋友圈画质怎么才能不被压缩视频)

  • ssd硬盘是什么意思(ssd是什么硬盘?)

    ssd硬盘是什么意思(ssd是什么硬盘?)

  • 小米青春版如何关闭HD(小米青春版如何截屏)

    小米青春版如何关闭HD(小米青春版如何截屏)

  • iphone11 128g够用吗(苹果11 128够用不)

    iphone11 128g够用吗(苹果11 128够用不)

  • 抖音入会是什么情况(抖音入会有什么坏处)

    抖音入会是什么情况(抖音入会有什么坏处)

  • 惠普打印机无线密码(惠普打印机无线打印设置)

    惠普打印机无线密码(惠普打印机无线打印设置)

  • 腾讯课堂切屏出去老师知道吗(腾讯课堂切屏出去老师能看到我的屏幕吗?)

    腾讯课堂切屏出去老师知道吗(腾讯课堂切屏出去老师能看到我的屏幕吗?)

  • 三星4521硒鼓什么型号(三星4521硒鼓什么拍照牌子的好)

    三星4521硒鼓什么型号(三星4521硒鼓什么拍照牌子的好)

  • 小米手环依据什么监测睡眠(你知道小米手环)

    小米手环依据什么监测睡眠(你知道小米手环)

  • 手机强制关机怎么关(手机强制关机怎么设置)

    手机强制关机怎么关(手机强制关机怎么设置)

  • 抖音怎么开通无限关注(抖音怎么开通无人直播带货)

    抖音怎么开通无限关注(抖音怎么开通无人直播带货)

  • 微信号注销后手机号是不是就解绑了(微信号注销后手机号还可以注册吗,注册后是原微信嘛)

    微信号注销后手机号是不是就解绑了(微信号注销后手机号还可以注册吗,注册后是原微信嘛)

  • p30省电模式怎么关闭(华为p30pro省电模式)

    p30省电模式怎么关闭(华为p30pro省电模式)

  • 快手运营人员是干嘛的(快手运营岗)

    快手运营人员是干嘛的(快手运营岗)

  • 三星n9600是什么型号(三星n960u是什么型号)

    三星n9600是什么型号(三星n960u是什么型号)

  • 指纹锁识别不了指纹怎么办(指纹锁识别不了怎么办)

    指纹锁识别不了指纹怎么办(指纹锁识别不了怎么办)

  • 手机如何设置4g网络(苹果手机怎样设置4g网络)

    手机如何设置4g网络(苹果手机怎样设置4g网络)

  • ldnaloo这是什么型号(loadina是什么意思)

    ldnaloo这是什么型号(loadina是什么意思)

  • sbc什么意思(蓝牙音响sbc什么意思)

    sbc什么意思(蓝牙音响sbc什么意思)

  • 怎么看vivo23是不是幻彩版(vivo怎么看手机是不是新的)

    怎么看vivo23是不是幻彩版(vivo怎么看手机是不是新的)

  • win10固态128g够用吗(win10系统128g固态硬盘)

    win10固态128g够用吗(win10系统128g固态硬盘)

  • vivo存储卡怎么装(vivo手机存储卡怎么用)

    vivo存储卡怎么装(vivo手机存储卡怎么用)

  • Win11桌面图标如何任意摆放 Win11桌面图标随意摆放方法(win11桌面图标如何固定不动)

    Win11桌面图标如何任意摆放 Win11桌面图标随意摆放方法(win11桌面图标如何固定不动)

  • aiepk.exe是什么进程 aiepk是什么文件的进程(exe是什么进程)

    aiepk.exe是什么进程 aiepk是什么文件的进程(exe是什么进程)

  • 20分钟,使用Amazon SageMaker快速搭建属于自己的AIGC应用

    20分钟,使用Amazon SageMaker快速搭建属于自己的AIGC应用

  • 个人所得税本期收入是扣完保险吗
  • 减免增值税如何结转
  • 土地价款抵扣增值税
  • 利税总额计算公式利润表怎么计算
  • 与企业日常无关的政府补服属于利得吗
  • 已认证发票对方红冲应该怎么做账
  • 金蝶财务软件固定资产怎样计提折旧
  • 复式记账法哪本书提到过?
  • 有差价的商品发票如何开具及注意事项
  • 公司收到虚开发票谁承担
  • 货运代理公司会计涉及的科目
  • 电子承兑银行承兑
  • 递延资产放在资产负债表哪里
  • 毁损材料的损失怎么算
  • 以物易物方式销售货物例题
  • 当月取得的进项必须当月勾选吗
  • 房租发票一下全部开出
  • 税款不申报会怎样
  • 一般纳税人差额征税怎么做账
  • 支付境外销售佣金怎么做
  • 一般纳税人证明在哪里打印
  • 增值税计入无形资产的入账价值吗?
  • 请问高人们旧房子要装修应怎样装
  • 对外投资公司经营范围
  • 出口佣金会计分录
  • 软件合同审核要点
  • 国税申报纳税调整项目怎么填的?
  • 批发零售的成本核算
  • 软件开发公司怎么选择
  • 存货年末余额怎么算出来的
  • 承兑汇票如何背书转让
  • 契税减免备案材料是什么
  • 固定资产处置要交所得税吗
  • 在建工程会计科目
  • php字符串函数大全
  • linux device drivers
  • incredicle
  • php使用memcache
  • 土地增值税预征的计征依据=预收款-应预缴增值税税款
  • 工程审计需要什么条件
  • 计提坏账准备的方法
  • 货运代理开票
  • 没报关的货物还需要开发票嘛
  • html怎么嵌套php
  • 以前年度损益调整结转到哪里
  • 财务会计制度或纳税人财务会计核算办法
  • 新必应申请使用资格
  • php常用的打印函数
  • 个税赡养老人作废后无法修改
  • 还有什么服务啊
  • 个体户注销工商需要等公示时间结束吗?
  • 收购发票加计扣除会计分录
  • 以前年度无形资产摊销
  • 房租费用能计入什么科目
  • 转让不动产怎么计算增值税
  • 无形资产当月减少当月计提吗
  • 稳岗补贴如何入账
  • 本年利润是负数的会计分录
  • 密码区出框
  • 购买本公司产品未付款需要签名字吗
  • 怎样编制银行存款凭证
  • sqlserver获取uuid
  • mssql注入使用命令
  • mysql版本信息
  • xp系统浏览器收藏夹文件位置
  • ubuntu没有wlan0
  • freebsd 添加用户
  • mac steam一直更新
  • Win RT 8.1 Update 3怎么提前更新安装使用?
  • linux isolcpus
  • windows8介绍
  • win8的ie浏览器
  • jquery实现select选择框内容左右移动代码分享
  • 搭建安卓开发环境必须的工具
  • 加密批处理代码
  • jquery与js
  • bootstrap基础教程
  • 国家税务局总局黑龙江分局
  • 山东税务社保费用缴纳
  • 金税盘白盘如何换纽扣电池
  • 免责声明:网站部分图片文字素材来源于网络,如有侵权,请及时告知,我们会第一时间删除,谢谢! 邮箱:opceo@qq.com

    鄂ICP备2023003026号

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

    友情链接: 武汉网站建设