數組

數組:是一種線性表數據結構,用一組連續存儲空間,存儲相同類型的數據。java

線性表

數據排成一條線同樣的存儲結構,在線性表中,數據之間相互關係只有先後關係,除了數組以外,還有鏈表、隊列、棧等。算法

與線性表對應的就是非線性表結構,數據之間不止簡單的先後關係,好比:二叉樹、堆、圖等。數組

連續存儲空間和相同類型的數據

數組不只要在邏輯上連續,也要在物理上連續。在內存中就要求必須是連續存儲,從而致使數組在新增或刪除一個數據的時候,爲了保證連續性,就須要作大量數據搬移操做。數據結構

同時數組也具備"隨機訪問"特性,能夠根據下標直接訪問數據中的數據。計算機會給每塊內存分配地址,經過尋址公式計算出內存地址,就能夠直接訪問。性能

這個公式也能夠解釋下爲何數組下標是從0開始的?優化

//base_address爲首地址,i爲數組下標,data_type_size爲數組中每一個元素所佔大小
a[i]_address = base_address + i * data_type_size

數組操做

理解誤區

「數組適合查找,查找操做的時間複雜度爲O(1)」,這句話表達不夠準確,數組更加適合查找操做,可是查找的時間複雜度並不爲O(1),即便排好序的數組,使用二分查找時間複雜度也爲O(logn),數組支持隨機訪問,根據下標隨機訪問的時間複雜度爲O(1)。code

插入操做

假設一個數組長度爲n,將一個數據插入到第k個位置,就須要將k到n的數據所有日後移一位,這樣最好的時間複雜度爲O(1),最壞時間複雜度爲O(n),平均時間複雜度爲O(n)。隊列

若是數組中數據有序,插入新數據就須要按照剛纔的方法;若是數據無序,則能夠進行優化,最簡單的辦法就是直接將第k位數據搬移到數組最後,將新元素直接放入第k位。內存

刪除操做

刪除和插入同樣,爲了保持連續性,須要進行搬移數據,最好的時間複雜度爲O(1),最壞時間複雜度爲O(n),平均時間複雜度爲O(n)。ci

優化:在特殊場景下,能夠將屢次刪除操做集中一塊兒進行,能夠先記錄下已經刪除的數據。每次的刪除操做並非真正地搬移數據,只是記錄數據已經被刪除。當數組沒有更多空間存儲數據時,咱們再觸發執行一次真正的刪除操做,這樣就大大減小了刪除操做致使的數據搬移。(JVM 標記清除垃圾回收算法的核心思想)

ArrayIndexOutOfBoundsException

Java 自己就會作越界檢查,數組下標越界就會拋出 java.lang.ArrayIndexOutOfBoundsException。

總結

  1. Java ArrayList 沒法存儲基本類型,好比 int、long,須要封裝爲 Integer、Long 類,而 Autoboxing、Unboxing 則有必定的性能消耗,因此若是特別關注性能,或者但願使用基本類型,就能夠選用數組。
  2. 若是數據大小事先已知,而且對數據的操做很是簡單,用不到 ArrayList 提供的大部分方法,也能夠直接使用數組。
  3. 還有一個是我我的的喜愛,當要表示多維數組時,用數組每每會更加直觀。好比 Object[][] array;而用容器的話則須要這樣定義:ArrayList > array。

補充

數組拷貝複製、擴容

//擴容
newElementData = Arrays.copyOf(oldElementData, newCapacity);

//複製
System.arraycopy(被複制的數組A, 從A哪一個下標開始複製, 複製到哪一個數組B, 複製到B從哪一個下標開始, 複製長度);
//實現元素右移
System.arraycopy(elementData, index, elementData, index + 1, size - index);
相關文章
相關標籤/搜索