源码之ArrayList

Posted 保护眼睛

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了源码之ArrayList相关的知识,希望对你有一定的参考价值。

源码之ArrayList

ArrayList:
在这里插入图片描述
底层是一个被transient修饰的object类型的数组,为什么要用transient来修饰呢?
被transient关键字修饰的变量不会被序列化、因为因为ArrayList数组elementData中有未使用的空间 ,如果没有使用的空间也序列化,势必会影响性能.ArrayList的动态数组elementData被transient 修饰的 那么反序列化后的ArrayList会丢失了原先的元素吗? ArrayList在序列化的时候会调用writeObject,反序列化时调用readObject 也就是自定义序列化,来实现序列化。所以不会丢失元素。
在这里插入图片描述
来看带参数的构造函数、如果Array List初始化的容量大于0的话、那么初始的数组的大小就是传入的参数的容量、如果传入放入参数是0的话、那么初始的数据指向了一个空的数组
在这里插入图片描述

如果初始的容量小于0的话那么就会抛出IllegalArgumentException的异常。
没有参数的构造函数的初始的数组也是一个空的数组、
在这里插入图片描述
在这里插入图片描述

TirmToSize函数用于将数组压缩为最小的单位、也就是去除数组中没有使用的空间。
如果数数组的长度大于存放的元素的个数的话、并且数组中的元素的个数大于0的话、那么就是进行数组元素的拷贝。
在这里插入图片描述
grow函数
在这里插入图片描述
grow函数是用来实现数组的扩容用的、新的容量是旧容量的1.5倍、如果新的容量小于minCapacity的话、新的容量变为minCapacity、如果扩容后的容量大于最大的容量的话、那么调用hugecapacity函数

在这里插入图片描述
IndexOf方法传入指定的元素、做非空的判断、如果传入的元素的值是null的话、那么就会使用== 来判断、否则的话就会使用equals方法来判断。找到元素的话、返回元素对应的下标、否则返回-1.

上面的方法是从数组的前面往后寻找、下面的函数时从数组的后面往前去寻找。

在这里插入图片描述

clone方法:调用的时Arrays.clone 方法来实现数组的克隆的。
在这里插入图片描述
get:得到指定索引出的值 set:将指定索引的值替换、返回旧的值。
都会首先对数组下标进行检查。
在这里插入图片描述
来看add方法:无参的add方法直接在数组的末尾处加上传入的值、加入值之前会对size+1做检查、此时如果时数组第一次添加值并且初始化的是没有传入参数、也就是调用的是ArrayList 的无参的构造方法的话、那么calculateCapacity计算的出的值就是1和10之间最大的、也就是10、那么传给ensureExplicitCapacity 的值也就是10、等于数组的length、不会扩容了、如果初始给定了数组的大小的话、假设初始指定的顺序表的大小为6、那么传出过来的值也是1、但是数组不是DEFAULTCAPACITY_EMPTY_ELEMENTDATA的、即使初始参数传入的时0的话、那么也不会是DEFAULTCAPACITY_EMPTY_ELEMENTDATA、数组是
EMPTY_ELEMENTDATA的、ensureExplicitCapacity 接受的参数是1,数组的长度如果初始的时候是0的话、那么1-0>0、就会扩容、初始的数组的大小不是0的话、那么就不会去扩容。
在这里插入图片描述
add将元素插入到指定的位置、先对插入的位置进行检查、确保数组的容量、调用System中的arraycopy函数来实现数组的转移、将index后的元素都向后移动一位、将add的元素的值直接放到数组的index的位置上、size++。
在这里插入图片描述
remove函数:移除指定index位置的元素或者移除指定元素、删除元素之后、调用的都是System.arraycopy方法来实现数组的移动的
在这里插入图片描述
在这里插入图片描述
来看ArrayList 中大量用到的System.arraycopy方法和Arrays.copyof()方法:
Arrays.copyof()调用的是另一个的copyOf的方法、这个copyOf的方法调用的也是System.arraycopy方法、所以我们来看System.arraycopy方法

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
该方法是native方法,也就是调用了系统的C/C++代码,在JDK中是看不到的,但在openJDK中可以看到其源码。该函数实际上最终调用了C语言的memmove()函数,它可以保证同一个数组内元素的正确复制和移动,比一般的复制方法的实现效率要高很多,很适合用来批量处理数组。
ArrayList基于数组实现,可以通过下标索引直接查找到指定位置的元素,因此查找效率高,但每次插入或删除元素,就要大量地移动元素,插入删除元素的效率低。

ArrayList 和 Linked List的区别:
1.底层数据结构
2.插入和删除是否受元素位置的影响
3.是否支持高效随机访问
4. 内存空间占用

以上是关于源码之ArrayList的主要内容,如果未能解决你的问题,请参考以下文章

数据结构之ArrayList

数据结构之ArrayList

数据结构之ArrayList

ArrayListLinkedList和Vector源码分析

java List子类源码分析

Java集合源码学习笔记ArrayList分析