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

  • 拼多多勋章在哪看(拼多多的勋章是什么意思)

    拼多多勋章在哪看(拼多多的勋章是什么意思)

  • WPS文档加密如何设置(wps文档加密如何取消设置)

    WPS文档加密如何设置(wps文档加密如何取消设置)

  • 微信已发朋友圈设置部分人可见怎么解除(微信已发朋友圈图片替换)

    微信已发朋友圈设置部分人可见怎么解除(微信已发朋友圈图片替换)

  • 设置隐私相机里面没有选项(设置隐私相机里面没有和平精英)

    设置隐私相机里面没有选项(设置隐私相机里面没有和平精英)

  • 微信语音翻译对方能看到吗(微信语音翻译对方知道吗)

    微信语音翻译对方能看到吗(微信语音翻译对方知道吗)

  • 荣耀手表1代和2代区别(荣耀watch1和2区别)

    荣耀手表1代和2代区别(荣耀watch1和2区别)

  • 云技术为什么叫云(云技术原来是什么意思)

    云技术为什么叫云(云技术原来是什么意思)

  • 4g5g手机有什么区别(4g5g手机有什么区别视频教程)

    4g5g手机有什么区别(4g5g手机有什么区别视频教程)

  • 移动宽带没有路由器可以上网吗(移动宽带没有路由器怎么回事啊)

    移动宽带没有路由器可以上网吗(移动宽带没有路由器怎么回事啊)

  • 主板点亮一下就灭了是哪的问题(主板一点亮就熄灭)

    主板点亮一下就灭了是哪的问题(主板一点亮就熄灭)

  • 苹果11开热点连不上(苹果11开热点连车机设置)

    苹果11开热点连不上(苹果11开热点连车机设置)

  • 红米k30pro什么时候上市(红米k30pro什么时候推送miui14)

    红米k30pro什么时候上市(红米k30pro什么时候推送miui14)

  • commander是什么程序(commander是什么意思)

    commander是什么程序(commander是什么意思)

  • 内存条32g和16g区别(内存条16g和32g可以一起用吗)

    内存条32g和16g区别(内存条16g和32g可以一起用吗)

  • 分两栏显示怎么设置(分为两栏显示)

    分两栏显示怎么设置(分为两栏显示)

  • 微信置顶文字怎么设置(微信置顶文字怎么设置苹果手机)

    微信置顶文字怎么设置(微信置顶文字怎么设置苹果手机)

  • PS怎么转CDR(ps怎么转cdr格式)

    PS怎么转CDR(ps怎么转cdr格式)

  • 华为mate30第一次充电需要注意什么(华为mate30第一次开机激活步骤)

    华为mate30第一次充电需要注意什么(华为mate30第一次开机激活步骤)

  • 淘宝pc端是什么意思(淘宝pc版是什么)

    淘宝pc端是什么意思(淘宝pc版是什么)

  • 蚂蚁森林二手回收怎么刷能量(蚂蚁森林二手回收在哪里)

    蚂蚁森林二手回收怎么刷能量(蚂蚁森林二手回收在哪里)

  • ios13如何安装字体(苹果13字体怎么安装)

    ios13如何安装字体(苹果13字体怎么安装)

  • oppoa9怎么开关机(oppoa9手机怎么关机按哪里能关机)

    oppoa9怎么开关机(oppoa9手机怎么关机按哪里能关机)

  • 苹果xsm功能介绍(苹果xs max功能介绍)

    苹果xsm功能介绍(苹果xs max功能介绍)

  • 阅读类app开发怎么外包(android阅读软件怎么开发)

    阅读类app开发怎么外包(android阅读软件怎么开发)

  • 无线路由器如何安装 无线路由器安装方法图文介绍(无线路由器如何桥接wifi信号)

    无线路由器如何安装 无线路由器安装方法图文介绍(无线路由器如何桥接wifi信号)

  • 雷尼尔山上空的银河星系,美国华盛顿州 (© Brad Goldpaint/Cavan)(雷尼尔国家公园攻略)

    雷尼尔山上空的银河星系,美国华盛顿州 (© Brad Goldpaint/Cavan)(雷尼尔国家公园攻略)

  • 增值税发票作废了税钱退还吗
  • 生产税净额计算实例
  • 资产组可收回金额包含商誉吗
  • 合并报表是按年还是按月
  • 应付余额是负数怎么理解
  • 个人劳务费 税
  • 建筑工程管理费包括哪些内容
  • 发生哪些情形的应判定为重大电力安全隐患
  • 无票收入申报时要填税率吗
  • 预收电费结转成本怎么办
  • 给员工发中秋福利
  • 税控设备全额抵扣政策
  • 收到技术咨询费摘要
  • 税目与应纳税额的关系
  • 小规模纳税人开专票
  • 免税销售额扣除项目本期实际扣除额
  • 劳务清包工可以开3个点的票么
  • 电商刷单的收入怎么做凭证?
  • 初级备考需要多长时间
  • 工程收入怎么算
  • 已申报未导入什么意思呀
  • 吸收合并企业的情形
  • 合伙企业个人所得税计算案例
  • 以前年度少计费用,调整分录
  • 个体工商户需要办公户吗
  • 为什么盈余公积补亏不会影响留存收益
  • 工业企业生产成本核算表
  • 简易征收做账
  • 苹果手机铃声删除在哪里
  • php yii框架
  • 分公司不纳入合并
  • 老板垫付的货款会计分录
  • 个体户不建账怎样处罚
  • php正则表达式匹配字符串
  • 在金税卡里面如何交社保
  • thinkphp怎么用
  • 无法登陆p.to
  • 售后回购怎么做会计处理
  • 企业销售旧固定资产税票开票
  • 二手固定资产怎么折旧
  • poi java 导入导出
  • 个人劳务费可以开什么类目?
  • 用友t3核算管理如何取消记账
  • 小规模纳税人专票税率是多少
  • 员工工资扣工作服押金怎么做账呢
  • 小规模建筑公司开劳务费发票税率
  • 检测费可以抵扣吗
  • 增值税普通发票查询真伪
  • 购入投资性房地产支付的相关税费
  • 金税盘减免税款分录
  • 产品成本计算中最基本的方法是
  • 2023年职工养老保险缴费标准
  • 分析企业盈余状况
  • sqlserver的sql文件导入mysql
  • mysql存储过程菜鸟教程
  • hyper-v怎么样
  • win8.1使用
  • csinsmnt.exe进程的作用介绍 csinsmnt是什么进程
  • 电脑主板故障分析与判断
  • xp系统如何共享文件夹怎么弄
  • 在windowsxp中设置控制计算机硬件设备
  • freelibrary 程序崩溃
  • linux的newgrp
  • js怎么理解
  • 简单强悍是哪首歌
  • 文件夹如何取名字
  • jquery插件库怎么导入
  • python从入门到精通第三版pdf下载
  • unity 3d完全自学教程
  • javascript要怎么学
  • ExpandableListView 实现分组购物车
  • jquery代码实例
  • android view类
  • Jquery $when done then的用法详解
  • 如何在电子税务局添加办税人员
  • 2020百望税控盘最新系统
  • 出成效的意思
  • 个人有关事项核查情况的报告
  • 财务年中工作总结简短
  • 如何查询海关进口货物报关单
  • 免责声明:网站部分图片文字素材来源于网络,如有侵权,请及时告知,我们会第一时间删除,谢谢! 邮箱:opceo@qq.com

    鄂ICP备2023003026号

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

    友情链接: 武汉网站建设