Java集合源碼分析之基礎(一):數組與鏈表

數組鏈表是數據結構中最基本的部分,也是其他衆多數據結構的基礎。即便在Java中,這兩種結構使用的也很廣泛。這裏咱們會先對它們進行簡要分析。java

數組

在java中,數組定義爲一種基本類型,其能夠經過下標獲取到對應位置的數據。那麼這種結構的數據,在內存中是怎麼存放的呢?git

數組的結構示意圖

正如上圖所示,數組在內存中是一段連續的存儲單元,每一個數據依次放在每一個單元中。分析這種結構,咱們能夠得出如下幾個結論:github

  • 建立一個數組,必須聲明其長度,以在內存中尋找合適的一段連續存儲單元。這也意味着數組的大小是固定的,咱們沒法動態調整其大小。編程

  • 想要獲取數組中第i個元素,其時間複雜度是 O(1),由於能夠根據其地址直接找到它。同理修改也是。數組

  • 數組對查詢表現通常,要想查找一個元素,須要遍歷,時間複雜度爲O(n)微信

  • 由於地址連續,想要在數組中插入一個元素是複雜的,由於從插入位置起,後邊的全部元素都須要向後移動一位。同理刪除也是,只是移動方向爲向前。而且,當數組存滿時,就沒法繼續插入了。數據結構

  • 由於數組要佔據一整塊內存,有可能產生許多的碎片,也可能由於找不到合適的內存塊,而致使存儲失敗。源碼分析

總結起來就是:數組大小固定,查找迅速,增刪複雜,須要完整的內存塊,容易產生碎片。post

鏈表

鏈表是一種離散存儲結構,其在內存中存儲不是連續的,每一個數據元素都經過一個指針指向其下一個元素的地址。根據指針域的不一樣,鏈表又分爲單鏈表、雙向鏈表、循環鏈表等,這裏咱們只分析單鏈表。示意圖以下所示: 3d

鏈表的結構示意圖

分析這種結構,咱們能夠得出如下幾個結論:

  • 聲明一個鏈表時,不須要知道其長度,也不須要連續的內存塊,因此其大小能夠動態調整。

  • 鏈表的每一個元素都分爲數據域和指針域,前者是實際存儲的數據,後者則指向下一個元素的地址。和數組相比,每一個元素須要佔用的內存更大了。

  • 要獲取鏈表的第 i 個元素變得複雜,由於其地址存放在它上一個元素的指針域裏,因此只能從第一個元素起,進行 i 次操做。同理修改也是。

  • 鏈表對查詢表現也通常,須要遍歷,時間複雜度爲O(n)

  • 增長與刪除一個元素更方便了,由於沒有對內存地址的限制,咱們只須要在對應節點合理處理下指針域的值,就能夠把一個元素插入鏈表或者從鏈表刪除。

  • 鏈表對內存的要求很小,只要可以存儲下一個數據元素的內存塊均可以使用,所以不會形成碎片化。

總結起來就是:大小能夠動態調整,增刪迅速,查找較慢,數據元素所佔內存略多,不須要整塊內存塊,不會形成碎片化。

數組與鏈表的選擇

經過以上分析,數組鏈表對咱們影響最大的幾點區別在於:

  • 數組按位置查找迅速,鏈表增刪方便
  • 數組是固定大小,鏈表能夠隨時擴充與縮減
  • 鏈表每一個元素佔據內存略多於數組
  • 數組和鏈表在查詢方面表現都比較通常,耗時較長

在數據量很小,內容基本固定時,咱們選擇何種數據結構的影響並不大。但當數據量較大時,若是咱們須要對數據進行頻繁的插入刪除,咱們應該選擇鏈表,若是咱們須要頻繁的獲取某個位置的元素,咱們應該選擇數組。數組與鏈表並無明確的優劣之分,根據不一樣的使用場景進行不一樣的選擇,纔是這兩種結構使用的最佳方式。

上一篇:Java集合源碼分析之開篇

下一篇:Java集合源碼分析之基礎(二):哈希表

本文到此就結束了,若是您喜歡個人文章,能夠關注個人微信公衆號:大大紙飛機

或者掃描下方二維碼直接添加:

公衆號

您也能夠關注個人github:https://github.com/LtLei/articles

編程之路,道阻且長。惟,路漫漫其修遠兮,吾將上下而求索。

相關文章
相關標籤/搜索