JAVA ArrayList集合底层源码分析

目录
ArrayList集合
- 一、ArrayList的注意事项
二、 ArrayList 的底层操作机制源码分析(重点,难点.)
- 1.JDK8.0
- 2.JDK11.0
arraylist集合">ArrayList集合
一、ArrayList的注意事项
ArrayList集合可以加入null,并且可以加入多个ArrayList是由数组来实现的数据存储的ArrayList基本等同于Vetor,但是ArrayList是线程不安全的(执行效率高),在多线程下不建议使用ArrayList
二、 ArrayList 的底层操作机制源码分析(重点,难点.)
1.JDK8.0
- ArrayList中存放了一个Object类型的数组elementDate,什么类型都能往里面放
transient Object[] elementDate;transient,表示该属性不会被序列化
- 当创建
ArrayList对象时,如果使用的是无参构造器,则初始elementData容量为0,第1次添加,则扩容elementData为10,如需要再次扩容,则扩容elementData为1.5倍 - 如果使用的是指定大小的构造器,则初始
elementData容量为指定大小,如果需要扩容,则直接扩容elementData为1.5倍。
注意:
- mount 表示的该数组的修改次数
注意:
>>1代表二进制位向右移两位,表示大小/2,这里的int newCapacity = oldCapacity + (oldCapacity >> 1),代表扩容按旧数组的1.5倍进行扩容(除第一次).newCapacity - minCapacity < 0- 第一次扩容:
newCapacity = 0,minCapacity = 10,即当最小容量比新容量小的时候,把minCpacaity赋给newCapacity,只有第一次扩容会执行这个if- 如果newCapacity 比最大的大小还要大时
- 执行hugeCapacity这个方法
- 利用
copyOf,把原数组的内容拷贝到新数组里面去,并让elementData指向该方法返回回来的地址,这样可以在保留原来数组中元素的同时,并增加新的空间,新空间默认为null;
- 第一次扩容:
若是使用指定大小的构造器
- 第一次扩容就按照elemenData的1.5倍扩容
- 整个执行流程还是和前面讲的一样
2.JDK11.0
使用ArrayList无参构造器,会创建一个只读的静态的,类型为Object的空数组
存储数据底层实现原理:
- 调用add方法,参数:
e为你要存储的数据(大概). modCount:为对该集合的操作次数,默认为0- 调用 add 方法(重载后的add方法)
- 当前元素个数 == 当前数组长度,就会进行扩容
- 之后让
elementData[s] = e,s为当前元素个数,且让size = s +1;
- 之后让
- 如果要进行扩容
- 返回一个扩容后的数组,利用
copyOf方法,把原来的数组元素,拷贝到新数组中,且新数组的长度为原来数组+1; - 然后在执行下面的赋值操作,同上
newCapacity方法
- 调用newCapacity,确定要扩大的空间
- oldCapacity 为当前数组的长度
- newCapacity 为扩容后新数组的长度:为旧数组长度的1.5倍
如果新数组的长度,比需要的(最小)容量小,则执行下面的代码
DEFAULT_CAPACITY为int 类型 ,值为10,如果elementaData 为空数组(DEFAULTCAPACTY_EMPTY_ELEMENTDATA),那么就用把mincapacity和DEFAULT_CAPACITY传进去进行比较,返回最大值,这个最大值就是要新数组的容量- 如果minCapacity<0 则抛出异常
- 并返回mincapacity
如果新数组的长度,大于需要的(最小)容量,则执行下面的代码
- 三元表达式,这里比较简单不做阐述
以上是 JAVA ArrayList集合底层源码分析 的全部内容, 来源链接: utcz.com/z/394301.html
