ArrayList源码解析(JDK1.8)

(第一次写博客,写得不好的地方请多多包涵 本人大二,有志同道合的朋友可以一起学习)

1、继承关系

ArrayList是基于动态数组实现,数组是根据索引来查找,所以查询较快,与数组相比,它的容量能动态的增长

由上图可知它继承于AbstractList,实现了List, RandomAccess, Cloneable, java.io.Serializable这些接口,所以它也具有随机访问、克隆、可序列化等一些列功能。

2、相关成员变量

defalut_capacity:默认初始容量。

empty_elementdata:空数组,调用无参构造时默认给个空数组

default tacpacity_empty_elementdata:也是一个空数组。将它与empty_elementdata分开,以便确定当添加了第一个成员之后扩充多大

elementData:动态数组,

size:动态数组的实际大小

3、构造函数

指定初始容量的构造函数

 

指定collection构造的构造函数

4、添加数据

首先会进入到一个valueOf方法,因为我定义的是一个Integer的list所以当我存入一个int值的时候,会调用Integer类的静态方法valueOf(如果整型字面量的值在-128到127之间,那么不会new新的Integer对象,而是直接引用常量池中的Integer对象)这个简单了解即可

进入到add方法,这时size为0并且elementData也为一个空数组(图①用的无参构造,默认容量为10,并赋一个空的object数组给elementData)并至少容纳minCapacity个成员数量

进入到ensureCapacityInternal方法中,调用ensureExplicitCapacity,在此之前会先调用calculateCapacity方法

判断elementData是否为空,是就返回默认容量和minCapacity中的最大的哪一个 否则直接返回minCapacity

由图④可知此时进入ensureExplicitCapacity方法 (modCount用来记录修改次数,主要用于多线程环境下) 判断是否需要进行扩容 

oldCapacity存储旧容量,newCapacity存储新容量,也就是扩容之后的

newCapacity等于oldCapacity加上oldCapacity左移一位(右移一位就是除以2的1次方,位运算要快于整除) 从这里也就可以看出Arraylist是以1.5倍来扩容的

如果扩容之后的newCapacity < oldCapacity 那么还是以原来的

如果扩容之后的newCapacity> max_array_size(2147483639) 那么就得调用hugeCapacity方法(但这个hugeCapacity估计也不会用到)

这里max_array_size=Integer.max_value-8

注意subList方法

我们经常会想只操作特定范围内的数据 那么就会用到subList 但这里直接调用subList方法的时候需要注意会改变原list 我们先跟进去看看

subListRangeCheck方法会先检测下你指定范围是否合法

然后再new一个新集合 但从上图可以看到 这里传了this 也就是说传入原list进去(这里subList是个内部类)

进入SubList的构造后 我们发现它的size是为我指定范围的长度 offset是指当前subList在原list中的起始位置 

所以此时的add操作 会对原list进行操作 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值