【源码解析】- ArrayList源码解析,绝对详细 (2)

指定index添加元素

public void add(int index, E element) { // 检查index rangeCheckForAdd(index); // 是否需要扩容操作,记录modCount ensureCapacityInternal(size + 1); // Increments modCount!! // 进行数组拷贝,给这个添加的元素腾出一个位置index System.arraycopy(elementData, index, elementData, index + 1,size - index); // 在这个位置index放置元素 elementData[index] = element; size++; } private void rangeCheckForAdd(int index) { if (index > size || index < 0) throw new IndexOutOfBoundsException(outOfBoundsMsg(index)); } private String outOfBoundsMsg(int index) { return "Index: "+index+", Size: "+size; }

我们看到哈,在添加元素的方法中,原则是计算容量,判断是否需要扩容,并记录修改次数。这里有一个非常重要的方法就是数组拷贝。扩容需要拷贝,在指定index中放入元素也需要拷贝哈。下面我们通过画图的方式来解释一下System.arraycopy这个函数

System.arraycopy详解

这是System类中的一个静态方法,用来实现数组之间的复制,具体的实现我们就不去了解,我们主要来看看他的用法,以及在ArrayList是怎么使用的

public static native void arraycopy(Object src, int srcPos, Object dest, int destPos, int length);

参数说明

src:the sourse arr 源数组

srcPos:starting position in the source array. 源数组的起始位置

dest:the destination array. 目标数组

destPos:starting position in the destination data. 目标数组的起始位置

length:the number of array elements to be copied. 复制的长度

举几个例子

// 给定数组 int[] src = {1,2,3,4,5}; // 给定目标数组 int[] dest = new int[src.length] // 要求1 将src 数组全部复制到dest中 System.arraycopy(src,0,dest,0,src.length); // 要求2 将src的前三位数复制到dest中的后三位 System.arraycopy(src,0,dest,2,src.length-2); 数组拷贝图解

grow扩容拷贝

【源码解析】- ArrayList源码解析,绝对详细

假定当前我们的集合元素已经有10个了,此时还需要添加一个元素。会经历这样的操作。

1、判断需要扩容,新的容量为15的数组。

2、将源数组拷贝到新的数组中,重新复制给elementData;

3、在index=10的位置添加元素

add index 移动拷贝

【源码解析】- ArrayList源码解析,绝对详细

在集合中已经有了5个元素了。现在需要在index=1的位置插入一个新的元素,可以理解成插队。

1、判断是否需要扩容。这里发现不需要

2、System.arraycopy(elementData, index, elementData, index + 1,size - index);

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zzpdgz.html