转载

[原]Java集合类源代码分析二:ArrayList(2)

继续上一篇博客介绍,

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源代码就介绍完成了,知道这些源码之后要知道它的数据结构其实是数组,而且通过调整数组长度来避免数组带来的不能扩展的弊端,但是这样一来带来的性能是需要考虑的,所以如果在初始化的时候进行能够传入大小就传入大小,如果不清楚大小长度那么就可能会出现性能下降的问题,所以这一点是需要注意的。

正文到此结束
Loading...