ArrayList和Array是我們在實際編程中經常使用的容器,而且因為ArrayList相當於動態化的數組,所以它們之間有太多的相似,以至於我們在選擇哪種來儲存元素的時候,會有小小的迷惑。
那麼,這兩者的區別和適用場合分別是什麼呢?
一存放的內容
數組,存放的一定是同種類型的元素,而ArrayList不一定,因為它可以儲存Object,但數組也可以是一個Object數組,然後再提取出我們想要的類型,這種做法是不會丟失資訊的(Object不能轉化為基本類型,但是基本類型都有相對應的封裝類),況且我們ArrayList本身內部封裝的數組就是Object數組,所以,它的實質就是一個Object數組。
二ArrayList的優缺點
使用ArraList的最大優點就是方便,因為我們可以使用它的方法來進行操作,但是,因為ArrayList是內部封裝了Array的容器,所以,它的很多方法,像是IndexOf,Contains等等,其實都是以簡單的演算法在內部數組中進行遍曆,所以效率會有影響(但是這部分的影響真的是不用太過於在意)。
使用ArrayList的最大缺點就是當我們添加新的元素的時候,它是先檢查內部數組的容量是否足夠,如果不夠,它會建立一個容量為原來數組兩倍的新數組,然後將所有元素複製到新數組裡,接著拋掉舊數組。這點真的很麻煩,因為每次都要這麼搞,尤其是元素足夠多的時候,這就真的是既影響記憶體又影響效率的問題,但通過單獨測試它們的已耗用時間,發現其實差不多,最大的影響就是如果是有其他代碼也需要使用到記憶體,那麼Array依然不變,但是ArrayList就會變得慢多,相同情況下所花的時間是Array的四倍多(實際情況是遠遠不止)。
三ArrayList與Array的相互轉化
ArrayList因為內部是一個數組,所以它是可以轉化為數組的。方法如下:
List<Integer> list = new ArrayList<Integer>(); Integer[] marray = list.toArray(new Integer[list.getSize()]);
這樣就能將對應的list轉化為數組。我們的toArray()還有不帶參數的方法,但是這個方法的使用必須注意,因為我們的toArray()其實返回的是Object數組,所以,如果是像這樣調用:
Integer[] marray = (Integer)list.toArray();
是要出錯的。前面帶參數的toArray()之所以可以,是因為它的內部實現是根據傳進來的數組的元素類型再返回相應類型的數組,但是我們還是可以將marray中的每個元素強制轉化為對應的類型。所以,從使用的方便來看,我更傾向於使用帶參數的toArray(),而且上面是慣用法,我們在參數裡面傳進一個長度為list長度的相對應數組,就能返回一個我們想要長度的數組。
四兩者的適用場合
使用list的慣用聲明方式就是我們開頭的那樣:
List<Integer> list = new ArrayList<Integer>();
雖然我們想要的確實是ArrayList而不是list,但是我們知道,父類是可以獲得子類的引用並且使用子類的方法,所以這樣我們就能同時使用List和ArrayList的方法而不用害怕出錯了。說了這麼多區別,我們到底該如何使用它們呢?首先,一個重要的約束就是,List的聲明地區一般是在main方法裡(當然靜態list也可以,但是我們一般使用的時候都只是當做儲存元素的臨時容器),而Array是可以在外部進行聲明的,這時它就是全域數組。所以,就著這點,它們的使用已經有區別,如果想要儲存一些在整個程式運行期間都會存在而且不變的資料,我們可以將它們放進一個全域數組裡,但是如果我們單純只是想要以數組的形式儲存資料,方便我們進行尋找,那麼,我們就選擇ArrayList。而且還有一個地方是必須知道的,就是如果我們需要對元素進行頻繁的移動或刪除,或者是處理的是超大量的資料,那麼,使用ArrayList就真的不是一個好的選擇,因為它的效率很低,使用數組進行這樣的動作就很麻煩,那麼,我們可以考慮選擇LinkedList。