1. 程式人生 > 其它 >ArrayList與LinkedList

ArrayList與LinkedList

面試題:ArrayList、LinkedList、Vector三者的異同?
同:三個類都實現了List介面,儲存資料的特點相同:儲存有序的、可重複的資料。
不同:見下方分析。

1. List介面框架

Collection介面:單列集合,用來儲存一個一個的物件

  • List介面:儲存有序的、可重複的資料。 -->“動態”陣列,替換原有的陣列

    • ArrayList:作為List介面的主要實現類;執行緒不安全的,效率高;底層使用Object[] elementData儲存
    • LinkedList:對於頻繁的插入、刪除操作,使用此類效率比ArrayList高;底層使用雙向連結串列儲存
    • Vector:作為List介面的古老實現類;執行緒安全的,效率低;底層使用Object[] elementData儲存

2. ArrayList的原始碼分析:

jdk 7情況下:

  ArrayList list = new ArrayList();//底層建立了長度是10的Object[]陣列elementData
  list.add(123);//elementData[0] = new Integer(123);
  ...
  list.add(11);//如果此次的新增導致底層elementData陣列容量不夠,則擴容。

預設情況下,擴容為原來容量的1.5倍,同時需要將原有陣列中的資料複製到新的陣列中。
結論:建議開發中使用帶參的構造器:ArrayList list = new ArrayList(int capacity);

jdk8中ArrayList的變化:

  ArrayList list = new ArrayList();//底層Object[] elementData初始化為{},並沒有建立長度為10的陣列
  list.add(123);//第一次呼叫add()時,底層才建立了長度10的陣列,並將資料123新增到elementData[0]
  ...

後續的新增和擴容操作與jdk7無異。
小結:jdk7中的ArrayList物件的建立類似於單例的餓漢式,而jdk8中的ArrayList物件的建立類似於單例的懶漢式,延遲了陣列的建立,節省記憶體。

3. LinkedList的原始碼分析:

  LinkedList list = new LinkedList(); 內部聲明瞭Node型別的first和last屬性,預設值為null
  list.add(123);//將123封裝到Node中,建立了Node物件。

其中,Node定義為:體現了LinkedList的雙向連結串列的說法

  private static class Node<E> {
    E item;
    Node<E> next;
    Node<E> prev;

    Node(Node<E> prev, E element, Node<E> next) {
      this.item = element;
      this.next = next;
      this.prev = prev;
    }
  }

4. Vector的原始碼分析

jdk7和jdk8中通過Vector()構造器建立物件時,底層都建立了長度為10的陣列。
在擴容方面,預設擴容為原來的陣列長度的2倍。