1. 程式人生 > >ArrayList,LinkedList使用場景及效能說明

ArrayList,LinkedList使用場景及效能說明

大部分只能瞭解其大概使用方法,對其內部結構缺乏瞭解,錯誤的使用方式會導致效能大幅下降。 
   首先介紹ArrayList,顧名思義內部資料結構是陣列 
   private transient Object[] elementData;
   private int size;
   public ArrayList(int initialCapacity){
   }

   在增加元素時,若容量不足進行擴充 
    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);
	}
    }

   新陣列大小為之前陣列大小*1.5+1 ,加上1保證oldCapacity為1的情況也能擴充為2 
  (類似分頁時總頁數=(總記錄數+ (每頁記錄數-1))/每頁記錄數演算法) 

   刪除元素時通過 System.arraycopy把刪除位置後的所有元素前移一個位置實現 
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 do its work

	return oldValue;
    }



  LinkedList大家都知道是通過連結串列實現,內部是一個雙向連結串列 
public class LinkedList<E>
    extends AbstractSequentialList<E>
    implements List<E>, Deque<E>, Cloneable, java.io.Serializable
{
    private transient Entry<E> header = new Entry<E>(null, null, null);
    private transient int size = 0;
}
private static class Entry<E> {
	E element;
	Entry<E> next;
	Entry<E> previous;
}

插入和刪除都只要改動前後節點的next和previous實現 

總結特點如下: 
型別 內部結構 順序遍歷速度 隨機遍歷速度 追加代價 插入代價 刪除代價 佔用記憶體
ArrayList 陣列
LinkedList 雙向連結串列

所以: 
  • 一般順序遍歷情況下使用ArrayList,但注意建構函式中設定初始大小
  • 儘量不對ArrayList進行插入或刪除操作(刪除尾部除外),若有多次刪除/插入操作又有隨機遍歷的需求,可以再構建一個ArrayList,把複合條件的物件放入新ArrayList,而不要頻繁操作原ArrayList
  • 經常有刪除/插入操作而順序遍歷列表的情況下最適合使用LinkedList