ArrayList是基於數組實現的,是一個動態數組,其容量能自動增長,類似於C語言中的動態申請內存,動態增長內存。 LinkedList是基於雙向循環鍊錶(從原始碼中可以很容易看出)實現的,除了可以當做鍊錶來操作外,它還可以當作堆疊、佇列和雙端佇列來使用。
一、List的簡介
二、ArrayList
ArrayList的特點
ArrayList是基於陣列實作的,是一個動態數組,其容量能自動增長,類似於C語言中的動態申請內存,動態增長內存。
ArrayList是線程不安全的,只能用在單線程環境下,多線程環境下可以考慮用Collections.synchronizedList(List list)函數傳回一個線程安全的ArrayList類,也可以使用concurrent並發套件下的CopyOnWriteArrayList類。
ArrayList實現了Serializable接口,因此它支援序列化,能夠透過序列化傳輸
ArrayList實現了RandomAccess接口,支援快速隨機訪問,實際上就是透過下標序號進行快速存取
實作了Cloneable接口,能被複製
注意其三個不同的建構方法。無參構造方法建構的ArrayList的容量預設為10,帶有Collection參數的建構方法,將Collection轉換為陣列賦給ArrayList的實作陣列elementData,還有就是指定容量大小的建構方法。
注意擴充容量的方法ensureCapacity。 ArrayList每次增加元素(可能是1個,也可能是一組)時,都要呼叫該方法來確保足夠的容量。當容量不足以容納目前的元素個數時,就設定新的容量為舊的容量的1.5倍加1,如果設定後的新容量還不夠,則直接新容量設定為傳入的參數(也就是所需的容量),而後用Arrays.copyof()方法將元素拷貝到新的陣列(詳見下面的第3點)。從中可以看出,當容量不夠時,每次增加元素,都要將原來的元素拷貝到一個新的數組中,非常之耗時,也因此建議在事先能確定元素數量的情況下,才使用ArrayList ,否則建議使用LinkedList。
ArrayList的實作中大量地呼叫了Arrays.copyof()和System.arraycopy()方法。我們有必要對這兩種方法的實現做下深入的了解。
首先來看Arrays.copyof()方法。它有很多重載的方法,但實作思維都是一樣的,我們來看泛型版本的源碼:
public static <T> T[] copyOf(T[] original, int newLength) { return (T[]) copyOf(original, newLength, original.getClass()); }
很明顯地呼叫了另一個copyof方法,該方法有三個參數,最後一個參數指明要轉換的資料的類型,其來源碼如下:
public static <T,U> T[] copyOf(U[] original, int newLength, Class<? extends T[]> newType) { T[] copy = ((Object)newType == (Object)Object[].class) ? (T[]) new Object[newLength] : (T[]) Array.newInstance(newType.getComponentType(), newLength); System.arraycopy(original, 0, copy, 0, Math.min(original.length, newLength)); return copy; }
這裡可以很明顯地看出,該方法實際上是在其內部又創建了一個長度為newlength的數組,呼叫System.arraycopy ()方法,將原來數組中的元素複製到了新的數組中。
下面來看System.arraycopy()方法。這個方法被標記了native,呼叫了系統的C/C 程式碼,在JDK中是看不到的,但在openJDK中可以看到其原始碼。該函數實際上最終調用了C語言的memmove()函數,因此它可以保證同一個數組內元素的正確複製和移動,比一般的複製方法的實現效率要高很多,很適合用來批量處理數組。 Java強烈建議在複製大量數組元素時使用該方法,以取得更高的效率。
注意ArrayList的兩個轉化為靜態數組的toArray方法。
第一個,Object[] toArray()方法。此方法有可能會拋出java.lang.ClassCastException異常,如果直接用向下轉型的方法,將整個ArrayList集合轉變為指定類型的Array數組,便會拋出該異常,而如果轉化為Array數組時不向下轉型,而是將每個元素向下轉型,則不會拋出該異常,顯然對數組中的元素一個個進行向下轉型,效率不高,且不太方便。
第二個,8742468051c85b06f0a0af9e3e506b5c T[] toArray(T[] a)方法。此方法可以直接將ArrayList轉換得到的Array進行整體向下轉型(轉型其實是在該方法的源碼中實現的),且從該方法的源碼中可以看出,參數a的大小不足時,內部會調用Arrays.copyOf方法,該方法內部會建立一個新的數組返回,因此對該方法的常用形式如下:
public static Integer[] vectorToArray2(ArrayList<Integer> v) { Integer[] newText = (Integer[])v.toArray(new Integer[0]); return newText; }
ArrayList基于数组实现,可以通过下标索引直接查找到指定位置的元素,因此查找效率高,但每次插入或删除元素,就要大量地移动元素,插入删除元素的效率低。
在查找给定元素索引值等的方法中,源码都将该元素的值分为null和不为null两种情况处理,ArrayList中允许元素为null。
三、LinkedList
LinkedList的特点
LinkedList是基于双向循环链表(从源码中可以很容易看出)实现的,除了可以当做链表来操作外,它还可以当做栈、队列和双端队列来使用;
LinkedList同样是非线程安全的,只在单线程下适合使用;
LinkedList实现了Serializable接口,因此它支持序列化,能够通过序列化传输;
实现了Cloneable接口,能被克隆;
相关推荐:
视频教程:
以上是java中的List:ArrayList、LinkedList實作介面的簡單介紹的詳細內容。更多資訊請關注PHP中文網其他相關文章!