Array, ArrayList, LinkedList之間的區別分析

(一)Array(數組類)
Java中最基本的數據結構,提供動態創建和訪問java數組的方法,根據定義的Array類型,其中的元素與類型必須相同。Array是一個固定大小的容器,底層採用的是線性連續空間來存放元素。

與Array容易混淆的還有Arrays(靜態類),專門用來操作array,提供數組的搜索、排序、複製等靜態方法。equals(), sort(), binarySearch()等。

與此相似,Collection 和 Collections 也是接口和靜態類的區別。java.util.Collection 是一個接口,是各種集合結構的父接口。實現他的主要類有Set 和 List.
java.util.Collections是一個專用靜態類,包含各種有關集合操作的靜態方法,提供一系列靜態方法實現對各種集合的搜索、排序、線程安全化等操作。

(二)ArrayList類

extends AbstractList
所有已實現的接口:
Serializable, Cloneable, Iterable, Collection, List, RandomAccess
直接已知子類:AttributeList, RoleList, RoleUnresolvedList

ArrayList同樣也是一個容器,但是其大小不固定,底層採用的也是線性連續空間來存放元素,當線性連續空間不足以存放元素時,又重新申請一片更大的空間(大約是原空間的2倍),將原有的內容移過去。

因此從這裏可以看出,Array要比ArrayList的效率高,因爲不需要重新申請空間。

每個 ArrayList 實例都有一個容量。該容量是指用來存儲列表元素的數組的大小。它總是至少等於列表的大小。隨着向 ArrayList 中不斷添加元素,其容量也自動增長。並未指定增長策略的細節,因爲這不只是添加元素會帶來分攤固定時間開銷那樣簡單。

在添加大量元素前,應用程序可以使用 ensureCapacity 操作來增加 ArrayList 實例的容量。這可以減少遞增式再分配的數量。

注意,此實現不是同步的。如果多個線程同時訪問一個 ArrayList 實例,而其中至少一個線程從結構上修改了列表,那麼它必須 保持外部同步。(結構上的修改是指任何添加或刪除一個或多個元素的操作,或者顯式調整底層數組的大小;僅僅設置元素的值不是結構上的修改。)這一般通過對自然封裝該列表的對象進行同步操作來完成。如果不存在這樣的對象,則應該使用 Collections.synchronizedList 方法將該列表“包裝”起來。這最好在創建時完成,以防止意外對列表進行不同步的訪問:
List list = Collections.synchronizedList(new ArrayList(…));
此類的 iterator 和 listIterator 方法返回的迭代器是快速失敗的:在創建迭代器之後,除非通過迭代器自身的 remove 或 add 方法從結構上對列表進行修改,否則在任何時間以任何方式對列表進行修改,迭代器都會拋出 ConcurrentModificationException。因此,面對併發的修改,迭代器很快就會完全失敗,而不是冒着在將來某個不確定時間發生任意不確定行爲的風險。

(三)LinkedList

LinkList也是一個容器,但底層採用的是鏈表,因此不存在擴容問題,除非整個內存空間都不足了,由於採用的是鏈表,因此查找效率也比較低,但刪除效率比較高。

//數組的大小是固定的,定義的時候已開闢好
String [][]array=new String[5][]; 

ArrayList的測試代碼:

[java]
//聲明一個數組對象,採用的是ArrayList,從這裏可以看出的是,ArrayList裏可以存放任意  
//類型,這也就是泛型  
ArrayList<String> array=new ArrayList<String>(); 
//在這個數組對象裏面存放元素  
array.add("test1"); 
array.add("test2"); 
//將值打印出來  
for(int i=0;i<array.size();i++) 
    System.out.println(array.get(i)); 

ArrayList核心源代碼:

public class ArrayList<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, java.io.Serializable 
{ 
    private static final long serialVersionUID = 8683452581122892189L; 

    /**
<SPAN style="WHITE-SPACE: pre"> </SPAN>從這裏,可以看出的是,ArrayList裏面是通過數組來存放元素的,數組名叫elementData,類型是Object
     */ 
    private transient Object[] elementData; 

    /**
     * 數組的尺寸,上面有個關鍵字transient,有些人沒見過,是用在Java的序列化時.
     *
     * @serial
     */ 
    private int size; 

    /**
     * Constructs an empty list with the specified initial capacity.
     *
     * @param   initialCapacity   the initial capacity of the list
     *下面這個是構造函數,從這裏可以看出,如果聲明時給構造函數傳遞了一個初始大小,則使用這個大小來開僻空間
     *            is negative
     */ 
    public ArrayList(int initialCapacity) { 
    super(); 
        if (initialCapacity < 0) 
            throw new IllegalArgumentException("Illegal Capacity: "+ 
                                               initialCapacity); 
    this.elementData = new Object[initialCapacity]; 
    } 

    /**
     * 如果使用默認構造函數,則默認情況下會開僻一個10B的大小空間
     */ 
    public ArrayList() { 
    this(10); 
    } 

參考地址:
1.Java API文檔http://tool.oschina.net/apidocs/apidoc?api=jdk-zh
2.http://www.2cto.com/kf/201308/232982.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章