从事javaWeb后端开发,集合的用处可以说是到处可见,数组由于大小是固定的,相对于动态扩容的集合来说,就用的不是那么多了。
今天我们就来分析下ArrayList集合类的源码了,希望可以帮助到你,首先我们还是从集合的入口慢慢深入分析吧。还是一贯风格,看代码咯。
List<String> stringList=new ArrayList<>();
通过new ArrayList(),我们跟进了这样的代码。
Tips:左右滑动可以看完整代码信息。
/**
上面的方法就是创建一个空集合,所以在new ArrayList()的时候就帮我们创建了一个空数组,我们还是看下elementData是如何定义的。
transient Object[] elementData; //这是一个Object[]数组用于存储任何类型的数据
好了,下面我们继续看下,我们在使用集合的add()方法时是个怎么样的过程吧,还是直接看程序代码。
上面的add()方法,就是将需要添加的元素e,添加到集合的末尾,也就是数组的末尾了,不过在看下面的流程之前,我们还是先分析一下ensureCapacityInternal()这个方法。
private void ensureCapacityInternal(int minCapacity) {
这两个方法主要是判断传入的size大小与默认值10进行比较,获取两者之中的最大值,然后调用ensureExplicaitCapacity()方法。
接下来我们可以ensureExplicaitCapacity()方法的代码主要做了什么。代码继续。
private void ensureExplicitCapacity(int minCapacity) {
上面的方法实现的是对传入的值和数组的length进行比较,满足条件直接进入grow()这个方法了,接下来我们继续看下grow()这个方法吧,看这样的代码需要一些耐心。
private void grow(int minCapacity) {
这个方法的功能就是,增加容量,以确保它至少可以容纳最小容量参数指定的元素,然后调用Arrays.copyOf()进行拷贝。其实我们再往下面进行代码的分析,就是下面这个方法的调用的。
Tips:左右滑动可以看完整代码信息。
System.arraycopy(original, 0, copy, 0,Math.min(original.length, newLength));
public static native void arraycopy(Object src, int srcPos,Object dest, int destPos,int length);
由于arraycopy是由native关键字修饰的,它是一个本地方法,而不是一个java方法,所以它是运行在本地方法栈的,而不是java栈,建议先进行了解下面的文章java内存区域划分详解好区分本地方法栈和java栈的区别。
上面的就是调用ArrayList类的add()方法的整个流程了,下面我们再看看其他方法吧。
先看下isEmpty()方法的代码。这个比较简单理解,代码看上去,一目了然。
public boolean isEmpty() {
下面继续分析其他方法吧,既然说到今天分享的是ArrayList类的代码分析,不能草草了事对不,也是自己公众号的初衷。
我们调用集合的size()方法就对应着下面的方法,这个size就是数组里面的元素个数大小。
public int size() {
看下集合是否包含某个元素的contains()方法咯。
public boolean contains(Object o) {
public int indexOf(Object o) {
上面的indexOf()方法,主要是对传入的对象obj分两种情况进行循环遍历判断,因为add()方法可以添加null值进去的,所以数组里面的元素可能就包含null值。
这时就需要我们按照两种方式,一个是对null值判断,另外一个是正常的元素值,循环遍历整个数组进行一一比较,返回对应的数组的下标值,如果两种遍历都没有找到就返回-1,所以contains()方法调用indexOf()方法就是对返回的数组下标进行了判断。
接下来我们还是慢慢分析吧,由于集合还是比较重要的,需要一点耐心。
我们看下集合的clear()方法的代码。
public void clear() {
clear()方法的功能是循环整个集合(数组)的大小,将每个集合元素都赋值为null,size赋值为0,这样就让JVM的GC机制来帮我们进行无用对象实例进行清除了,建议先移步到这java虚拟机,应该了解一点点先了解一下什么是JVM,本来不打算写下GC了,看来还是有必要的,后面构思一下,再写咯。
喜欢文章的可以关注,转发和分享一下文章,接下来我们看下集合的addAll()方法吧。
Tips:左右滑动可以看完整代码信息。
public boolean addAll(Collection<? extends E> c) {
ok,addAll()方法的功能解释已在代码对应位置说明了。
继续看下根据索引值获取对应元素的get()方法的代码吧,方法的功能和实现在代码中已说明,看注释信息就行了。
public E get(int index) {
既然数组可以转为集合,那么集合也可以转为数组,我们继续看下集合是如何转换为数组的方法toArray()方法。
public Object[] toArray() {
public static <T> T[] copyOf(T[] original, int newLength) {
我们继续看下Arrays.copyOf()方法,这里面涉及到静态工厂方法的内容,建立先看这部分内容java的静态工厂方法,先自己了解下。
其实下面调用的是个静态方法,进行数组之间的拷贝,返回数组。
public static <T,U> T[] copyOf(U[] original, int newLength, Class<? extends T[]> newType) {
集合的返回集合元素下标的indexOf()方法在上面的分析过程中已讲解。
上面我们说了indexOf()方法,接下来我们看下集合的lastIndexOf()方法。
public int lastIndexOf(Object o) {
是不是和indexOf()方法的写法很像,一个是从前往后遍历,一个是从后往前遍历进行判断,找不到就返回-1,同样的套路操作,希望可以帮助到你。
下面我们再看最后一个集合的remove()方法吧。
public boolean remove(Object o) {
集合的删除方法和indexOf()方法等都一样,都需要区分null值和非null值的,不过这里面调用了共同的fastRemove()方法,我们继续看下fastRemove()方法。
private void fastRemove(int index) {
好了,关于ArrayList集合类的源码分析到这里就结束了,希望这篇文章可以帮助到你,喜欢文章的可以关注公众号,进行转发和分享下文章,感谢你的阅读,期待遇到更好的自己。
本文分享自微信公众号 - WwpwW(gh_245290c1861a)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。