首頁  >  文章  >  Java  >  java中的List:ArrayList、LinkedList實作介面的簡單介紹

java中的List:ArrayList、LinkedList實作介面的簡單介紹

php是最好的语言
php是最好的语言原創
2018-07-26 14:22:003057瀏覽

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[] copyOf(T[] original, int newLength) {
    return (T[]) copyOf(original, newLength, original.getClass());
}

很明顯地呼叫了另一個copyof方法,該方法有三個參數,最後一個參數指明要轉換的資料的類型,其來源碼如下:

public static  T[] copyOf(U[] original, int newLength, Class 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 v) {  
    Integer[] newText = (Integer[])v.toArray(new Integer[0]);  
    return newText;  
}

ArrayList基于数组实现,可以通过下标索引直接查找到指定位置的元素,因此查找效率高,但每次插入或删除元素,就要大量地移动元素,插入删除元素的效率低。

在查找给定元素索引值等的方法中,源码都将该元素的值分为null和不为null两种情况处理,ArrayList中允许元素为null

三、LinkedList

LinkedList的特点

LinkedList是基于双向循环链表(从源码中可以很容易看出)实现的,除了可以当做链表来操作外,它还可以当做队列双端队列来使用;

LinkedList同样是非线程安全的,只在单线程下适合使用;

LinkedList实现了Serializable接口,因此它支持序列化,能够通过序列化传输;

实现了Cloneable接口,能被克隆;

相关推荐:

接口测试基础之入门篇

视频教程:

去除ArrayList集合中的重复自定义对象元素案例

以上是java中的List:ArrayList、LinkedList實作介面的簡單介紹的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn