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

  • 苹果13怎么换壁纸(苹果13怎么换壁纸下载)

    苹果13怎么换壁纸(苹果13怎么换壁纸下载)

  • 华为手机杂志锁屏如何设置(华为手机杂志锁屏怎么关闭)

    华为手机杂志锁屏如何设置(华为手机杂志锁屏怎么关闭)

  • 华为matex限量多少台

    华为matex限量多少台

  • 打印机墨水加错怎么补救(打印机墨水加错了怎么清理)

    打印机墨水加错怎么补救(打印机墨水加错了怎么清理)

  • 苹果相机分辨率怎么选择(苹果相机分辨率怎么调低)

    苹果相机分辨率怎么选择(苹果相机分辨率怎么调低)

  • 小米盒子不启动了怎么回事(小米盒子不启动怎么能恢复出厂设置)

    小米盒子不启动了怎么回事(小米盒子不启动怎么能恢复出厂设置)

  • 优酷vip到期缓存怎么看(优酷vip到期缓存还能看吗)

    优酷vip到期缓存怎么看(优酷vip到期缓存还能看吗)

  • 电脑屏幕死机卡住不能动了(电脑屏幕死机卡住不能动了鼠标能动)

    电脑屏幕死机卡住不能动了(电脑屏幕死机卡住不能动了鼠标能动)

  • 华为怎么智能呼叫小e(华为智能呼出)

    华为怎么智能呼叫小e(华为智能呼出)

  • 读写光盘的装置是什么(光盘的读写功能)

    读写光盘的装置是什么(光盘的读写功能)

  • 金士顿普条和骇客区别(金士顿普条和骇客神条有什么区别)

    金士顿普条和骇客区别(金士顿普条和骇客神条有什么区别)

  • 电脑结束进程后黑屏怎么办(电脑结束进程后又自动启动了)

    电脑结束进程后黑屏怎么办(电脑结束进程后又自动启动了)

  • 怎样把手机歌曲下载到u盘里(怎样把手机歌曲传到电脑上)

    怎样把手机歌曲下载到u盘里(怎样把手机歌曲传到电脑上)

  • 选择文档全文有几种方法(选择文档全文有什么用)

    选择文档全文有几种方法(选择文档全文有什么用)

  • jkmtl00是什么型号(华为jkmtl00什么型号的手机)

    jkmtl00是什么型号(华为jkmtl00什么型号的手机)

  • 微信怎么刷脸付款(微信上如何刷脸支付)

    微信怎么刷脸付款(微信上如何刷脸支付)

  • oppo的呼吸灯怎么设置(oppo呼吸灯怎么开启)

    oppo的呼吸灯怎么设置(oppo呼吸灯怎么开启)

  • 荣耀9x还是搭载安卓系统吗(荣耀9x算不算华为手机)

    荣耀9x还是搭载安卓系统吗(荣耀9x算不算华为手机)

  • 小米9 pro 5G上市时间(小米9pro上市时间及价格)

    小米9 pro 5G上市时间(小米9pro上市时间及价格)

  • wps段落设置在哪(wps段落设置在哪里找)

    wps段落设置在哪(wps段落设置在哪里找)

  • oppoa9怎么关机啊(oppoa9x怎么关机)

    oppoa9怎么关机啊(oppoa9x怎么关机)

  • ios定位修改(ios定位修改器)

    ios定位修改(ios定位修改器)

  • 旧手机号码导入新手机(旧手机号码导入sim卡)

    旧手机号码导入新手机(旧手机号码导入sim卡)

  • Win7旗舰版系统下设置IE浏览器的安全级别的方法(win7旗舰版系统怎么样)

    Win7旗舰版系统下设置IE浏览器的安全级别的方法(win7旗舰版系统怎么样)

  • 卷积神经网络 手写数字识别(包含Pytorch实现代码)(卷积神经网络有哪些)

    卷积神经网络 手写数字识别(包含Pytorch实现代码)(卷积神经网络有哪些)

  • 研发机构采购设计方案
  • 当期免抵税额如何做账
  • 财务软件大概多少钱
  • 增值税以物易物税收政策
  • 个税手续费怎么交增值税
  • 应收利息增加会计分录
  • 报完税没有清卡
  • 累计折旧和固定资产减值准备的区别
  • 经济法中企业营业收入包括哪些?
  • 建筑行业异地预缴增值税
  • 物业公司前期工作计划
  • 增值税与实际缴纳不符
  • 收到技术服务费计入什么科目
  • 收到的借款利息计入什么科目
  • 生产企业出口退税的计算方法
  • 工会经费向地方税务局缴纳的比例是多少
  • 小规模纳税人增值税账务处理
  • 特定行业如何界定
  • 资源税扣缴义务人代扣代缴税款的纳税义务发生时间
  • 金融企业的代理贷款什么意思
  • 充值销售技巧和话术总结
  • 分公司税款
  • 企业销售收入含不含税
  • 筹建期间的开办费包括哪些
  • 缴纳残保金和工龄有关吗
  • 年末存货怎么计算
  • 抵押质押的含义
  • 金税四期查到了怎么办
  • eml文件怎么打开方式
  • 吉隆坡石油双塔有多高
  • linux format命令
  • 公积金贷款所需手续
  • uni-app实战教程
  • PHP:imagesavealpha()的用法_GD库图像处理函数
  • 进出口公司出口退税额
  • 未到期的应收票据办理贴现会计分录
  • Yii中CArrayDataProvider和CActiveDataProvider区别实例分析
  • 增值税加计抵减怎么算
  • 产品报废进项税转出
  • 利息资本化怎么计算
  • 《linux内核分析》
  • 租赁业务成本
  • 企业从政府取得的非货币资产应该按照什么计量
  • 二季度报表是累计数吗
  • 预存电费余额怎么突然多了
  • python创建ndarray
  • 小规模纳税人免税额度是多少
  • 进销存的原理
  • 企业资产评估增值
  • 材料成本差异的超支与节约
  • 未收到货款发票是什么意思
  • 客户购买商品的三要素
  • 营业执照的注册号怎么查询
  • 农业技术人员是什么意思
  • 电子发票服务平台怎么下载发票
  • 营改增账务处理实例
  • 去年的凭证今年未入账
  • 会计帐本分为哪几类
  • 坏账损失的核算方法包括
  • 应付账款核算的项目
  • mysql基本介绍
  • sqlserver按时间查询
  • find linux命令详解
  • seg是什么文件
  • 怎样加快缩略图的大小
  • myfastupdate.exe - myfastupdate是什么进程文件 有什么用
  • shell脚本while true循环
  • 搭建nfs
  • 杨辉三角的代码
  • css怎么控制图片位置
  • 同一个页面
  • 文件包解密
  • jquery实现隔行变色的分享特效页面
  • windows下使用什么命令查看监听端口
  • 详解JavaScript对W3C DOM模版的支持情况
  • linux shell脚本攻略(第3版)
  • python 备份文件夹
  • 税务局的章
  • 上海自贸区税务大厅地址
  • 纳税服务投诉整改报告
  • 免责声明:网站部分图片文字素材来源于网络,如有侵权,请及时告知,我们会第一时间删除,谢谢! 邮箱:opceo@qq.com

    鄂ICP备2023003026号

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

    友情链接: 武汉网站建设