继续上一篇博客介绍,
public E get(int index) { RangeCheck(index); return (E) elementData[index]; }
Get方法其实就是从Object数组中取数据。
public E set(int index, E element) { RangeCheck(index); E oldValue = (E) elementData[index]; elementData[index] = element; return oldValue; }
Set方法有两个参数,第一个是索引,第二个是具体的值,作用就是将索引下的值变成传入参数的值。所以get方法实现是先将当前数组索引值的数据赋值到一个变量,此变量作为返回值传出,之后将当前的索引的值改成传入的值。
public boolean add(E e) { ensureCapacity(size + 1); // Increments modCount!! elementData[size++]= e; return true; }
Add方法是在数组后面添加一个元素,首先调用ensureCapacity方法,
public void ensureCapacity(int minCapacity) { modCount++; int oldCapacity = elementData.length; if (minCapacity > oldCapacity) { Object oldData[] = elementData; int newCapacity = (oldCapacity * 3)/2 + 1; if (newCapacity < minCapacity) newCapacity = minCapacity; // minCapacity is usually close to size, so this is a win: elementData = Arrays.copyOf(elementData, newCapacity); } }
这个方法首先将当前未添加的数组长度拿到,之后判断minCapacity(即size+1)是否大于oldCapacity,若大于,则调整容量为max((oldCapacity*3)/2+1,minCapacity),调整elementData容量为新的容量,即将返回一个内容为原数组元素,大小为新容量的数组赋给elementData;否则不做操作。
容量的拓展将导致数组元素的复制,多次拓展容量将执行多次整个数组内容的复制。若提前能大致判断list的长度,调用ensureCapacity调整容量,将有效的提高运行速度
后面的add(intindex, E element)和addAll(Collection<?extends E> c)以及addAll(int index,Collection<? extends E> c)都是和上面add方法实现思路类似。
下面看一下remove方法:
public E remove(int index) { RangeCheck(index); modCount++; E oldValue = (E) elementData[index]; int numMoved = size - index - 1; if (numMoved > 0) System.arraycopy(elementData, index+1, elementData, index, numMoved); elementData[--size] = null; // Let gc doits work return oldValue; }
这个方法主要是elementData[--size] = null这句话是可以让垃圾回收机制来收集。
public boolean remove(Object o) { if (o == null) { for (int index = 0; index < size; index++) if (elementData[index] == null){ fastRemove(index); return true; } } else { for (int index = 0; index < size; index++) if (o.equals(elementData[index])) { fastRemove(index); return true; } } return false; }
这个方法调用了fastRemove方法,这个方法实现的思路和remove(index)方法实现的思路是一致的。
后面还有一些其他的方法,在这里不再赘述,到这里对ArrayList源代码就介绍完成了,知道这些源码之后要知道它的数据结构其实是数组,而且通过调整数组长度来避免数组带来的不能扩展的弊端,但是这样一来带来的性能是需要考虑的,所以如果在初始化的时候进行能够传入大小就传入大小,如果不清楚大小长度那么就可能会出现性能下降的问题,所以这一点是需要注意的。