迎难而上ArrayList,源码分析走一波

JAVA 集合方面,第一个,必须得从 ArrayList 开始,毕竟 ArrayList 可以称得上是集合方面最常用的类了,估计没有之一 。

迎难而上ArrayList,源码分析走一波

文章插图
 
ArrayList 实现了 List 接口,是基于数组实现的 。小伙伴们都知道,数组的大小是固定的,创建的时候指定了大小,就不能再调整了,如果数组满了,就不能再添加任何元素了 。ArrayList 是数组很好的替代方案,它提供了比数组更丰富的预定义方法(增删改查),并且大小是可以根据元素的多少进行自动调整的,非常灵活 。
准备在 ArrayList 的第四个位置(下标为 3)上添加一个元素 55 。
迎难而上ArrayList,源码分析走一波

文章插图
 
此时 ArrayList 中第五个位置以后的元素将会向后移动 。
迎难而上ArrayList,源码分析走一波

文章插图
 
准备把 23 从 ArrayList 中移除 。
迎难而上ArrayList,源码分析走一波

文章插图
 
此时下标为 7、8、9 的元素往前挪 。
迎难而上ArrayList,源码分析走一波

文章插图
 
01、如何创建一个 ArrayListArrayList<String> alist = new ArrayList<String>();可以通过上面的语句来创建一个字符串类型的 ArrayList(通过尖括号来限定 ArrayList 中元素的类型,如果尝试添加其他类型的元素,将会产生编译错误),更简化的写法如下:
List<String> alist = new ArrayList<>();【迎难而上ArrayList,源码分析走一波】由于 ArrayList 实现了 List 接口,所以 alist 变量的类型可以是 List 类型;new 关键字声明后的尖括号中可以不再指定元素的类型,因为编译器可以通过前面尖括号中的类型进行智能推断 。
如果非常确定 ArrayList 中元素的个数,在创建的时候还可以指定初始大小 。
List<String> alist = new ArrayList<>(20);这样做的好处是,可以有效地避免在添加新的元素时进行不必要的扩容 。但通常情况下,我们很难确定 ArrayList 中元素的个数,因此一般不指定初始大小 。
02、向 ArrayList 中添加一个元素可以通过 add() 方法向 ArrayList 中添加一个元素,如果不指定下标的话,就默认添加在末尾 。
alist.add("王二");感兴趣的小伙伴可以研究一下 add() 方法的源码,它在添加元素的时候会执行 grow() 方法进行扩容,这个是面试官特别喜欢考察的一个重点 。
下面是 add(E e) 方法的源码:
public boolean add(E e) {modCount++;add(e, elementData, size);return true;}调用了私有的 add(E e, Object[] elementData, int s) 方法:
private void add(E e, Object[] elementData, int s) {if (s == elementData.length)elementData = https://www.isolves.com/it/cxkf/yy/JAVA/2020-07-30/grow();elementData[s] = e;size = s + 1;}然后调用了非常关键的 grow(int minCapacity) 方法:
private Object[] grow(int minCapacity) {int oldCapacity = elementData.length;if (oldCapacity > 0 || elementData != DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {int newCapacity = ArraysSupport.newLength(oldCapacity,minCapacity - oldCapacity, /* minimum growth */oldCapacity >> 1/* preferred growth */);return elementData = https://www.isolves.com/it/cxkf/yy/JAVA/2020-07-30/Arrays.copyOf(elementData, newCapacity);} else {return elementData = new Object[Math.max(DEFAULT_CAPACITY, minCapacity)];}}如果创建 ArrayList 的时候没有指定初始大小,那么 ArrayList 的初始大小就是 DEFAULT_CAPACITY:
private static final int DEFAULT_CAPACITY = 10;可以容纳 10 个元素 。
还可以通过 add(int index, E element) 方法把元素添加到指定的位置:
alist.add(0, "王三");add(int index, E element) 方法的源码如下:
public void add(int index, E element) {rangeCheckForAdd(index);modCount++;final int s;Object[] elementData;if ((s = size) == (elementData = https://www.isolves.com/it/cxkf/yy/JAVA/2020-07-30/this.elementData).length)elementData = grow();System.arraycopy(elementData, index,elementData, index + 1,s - index);elementData[index] = element;size = s + 1;}该方法会调用到一个非常重要的本地方法 System.arraycopy(),它会对数组进行复制(要插入位置上的元素往后复制,参照文章一开头提到的两张图片) 。
03、更新 ArrayList 中的元素可以使用 set() 方法来更改 ArrayList 中的元素,需要提供下标和新元素 。
alist.set(0, "王四");


推荐阅读