ArrayList與LinkList對比


本文簡要總結一下java中ArrayList與LinkedList的區別,這在面試中也是常常會問到的一個知識點。

先來看一下ArrayList和LinkedList的關系是怎樣的:

ArrayList與LinkedList的關系圖

從繼承體系可以看到,ArrayList與LinkedList都是Collection接口下List接口的實現類。可謂是一對雙胞胎。

但由於底層數據結構的不同導致ArrayList與LinkedList有本質上的區別。

ArrayList與LinkedList的區別

  • ArrayList:
        ArrayList是基於動態數組的數據結構。
        因為是數組,所以ArrayList在初始化的時候,有初始大小10,插入新元素的時候,會判斷是否需要擴容,擴容的步長是0.5倍原容量,擴容方式是利用數組的復制,因此有一定的開銷;
        另外,ArrayList在進行元素插入的時候,需要移動插入位置之后的所有元素,位置越靠前,需要位移的元素越多,開銷越大,相反,插入位置越靠后的話,開銷就越小了,如果在最后面進行插入,那就不需要進行位移;

  • LinkedList:
        內部使用基於鏈表的數據結構實現存儲,LinkedList有一個內部類作為存放元素的單元,里面有三個屬性,用來存放元素本身以及前后2個單元的引用,另外LinkedList內部還有一個header屬性,用來標識起始位置,LinkedList的第一個單元和最后一個單元都會指向header,因此形成了一個雙向的鏈表結構。
        LinkedList是采用雙向鏈表實現的。所以它也具有鏈表的特點,每一個元素(結點)的地址不連續,通過引用找到當前結點的上一個結點和下一個結點,即插入和刪除效率較高,只需要常數時間,而get和set則較為低效。

LinkedList的方法和使用和ArrayList大致相同,由於LinkedList是鏈表實現的,所以額外提供了在頭部和尾部添加/刪除元素的方法,也沒有ArrayList擴容的問題了。另外,ArrayList和LinkedList都可以實現棧、隊列等數據結構,但LinkedList本身實現了隊列的接口,所以更推薦用Lin 大專欄  ArrayList與LinkList對比kedList來實現隊列和棧。

總而言之,ArrayList和LinkedList的區別有以下幾點:
  •    ArrayList是實現了基於動態數組的數據結構,而LinkedList是基於鏈表的數據結構;
  •    對於隨機訪問元素,Array獲取數據的時間復雜度是O(1),但是要刪除數據卻是開銷很大的,因為這需要重排數組中的所有數據。ArrayList想要get(int index) 元素時,直接返回index位置上的元素,而LinkedList需要通過for循環進行查找,雖然LinkedList已經在查找方法上做了優化,比如index < size / 2,則從左邊開始查找,反之從右邊開始查找,但是還是比ArrayList要慢。
  •    對於添加和刪除操作add和remove,LinkedList是更快的。因為LinkedList不像ArrayList一樣,不需要改變數組的大小,也不需要在數組裝滿的時候要將所有的數據重新裝入一個新的數組,這是ArrayList最壞的一種情況,時間復雜度是O(n),而LinkedList中插入或刪除的時間復雜度僅為O(1)。
  •    ArrayList在插入數據時還需要更新索引(除了插入數組的尾部)。 ArrayList想要在指定位置插入或刪除元素時,主要耗時的是System.arraycopy動作,會移動index后面所有的元素;LinkedList主耗時的是要先通過for循環找到index,然后直接插入或刪除。這就導致了兩者並非一定誰快誰慢。

適用場景

很多場景下都是ArrayList更受歡迎。但有些情況下LinkedList更為合適,比如:

  1. 你的應用不會隨機訪問數據。因為如果你需要LinkedList中的第n個元素的時候,你需要從第一個元素順序數到第n個數據,然后讀取數據。

  2. 你的應用有更多的插入和刪除元素操作,更少的讀取數據。因為插入和刪除元素不涉及重排數據,所以它要比ArrayList要快。

以上就是關於ArrayList和LinkedList的差別。你需要一個不同步的基於索引的數據訪問時,請盡量使用ArrayList。ArrayList很快,也很容易使用。但是要記得要給定一個合適的初始大小,盡可能的減少更改數組的大小。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM