从源码角度解析ArrayList特性

说到ArrayList想必大家都不陌生,这绝对是我们日常开发高频使用的一个类。今天我也在这说道说道下ArrayList。
ArrayList是List的一个实现类,在我们的开发使用中主要用来存储对象。想必大家在面试的时候面试官经常会问List,Set,Map这三者的区别。有过工作经验的或者看过网上XXX面试宝典的人肯定都能信手拈来答上来。接下来我就来从源码的角度来说道说道ArrayList为什么具有这些特性。
1、ArrayList是有序的,可重复的。首先我们来看看ArrayList的源码
从源码角度解析ArrayList特性
从以上这段源码我们可以知道当我们通过调用ArrayList的add()方法往ArrayList添加元素的时候,其实我们添加的元素被保存到了elementData这个数组里。数组的特性大家都知道,它是有序的,也是可以重复的。所以ArrayList也就具备了这一特性

2、查询性能快
这一性能也是由数组决定的。当我们去取数据的时候,只要提供下标直接获取

3、插入性能慢
这一点可能起初一想会有点不对,想数组的插入应该也是很快的。例如a[1]="abc",这个性能应该是很块的。没错,这确实很快。但是它有个前提,数组的长度得是固定的。而我们的ArrayList它的长度是变化的,随着我们不停的往里面插入数据变化而变化的。接下来我们就来看看ArrayList的add()方法的源码,看看它为什么就慢了(这个是相对的)
从源码角度解析ArrayList特性
从源码角度解析ArrayList特性
在我们调用add()方法的时候首先会去执行ensureCapacityInternal()方法,我们来看看这个方法发生了点啥
从源码角度解析ArrayList特性
从这里我们可以看出来,首先ArrayList会去判断minCapacity(当前已经插入的元素长度+1)减去elementData的长度是否大于0。这句代码翻译过来就是判断elementData是否能否装的下当前要添加的元素,如果可以则直接插入数组。否则就得去grow(),即扩容。那么数组怎么扩容?肯定是new一个长度更大的新数组,然后将之前数组的数据copy过来。我们看看是不是这么回事
从源码角度解析ArrayList特性
所以想必现在大家对ArrayList插入为什么性能慢,有个比较深刻的映象了吧。当我们频繁大量的插入数据的时候那么ArrayList会不停的创建新数组,然后copy。
最后总结下ArrayList它不适合频繁、大量插入的场景。好了今天就先到这