1 概述
ArrayList是基於陣列實現的,是一個動態陣列,其容量能自動增長,類似於C語言中的動態申請記憶體,動態增長記憶體。
ArrayList不是執行緒安全的,只能用在單執行緒環境下,多執行緒環境下可以考慮用Collections.synchronizedList(List l)函式返回一個執行緒安全的ArrayList類,也可以使用concurrent併發包下的CopyOnWriteArrayList類。
ArrayList實現了Serializable介面,因此它支援序列化,能夠通過序列化傳輸,實現了RandomAccess介面,支援快速隨機訪問,實際上就是通過下標序號進行快速訪問,實現了Cloneable介面,能被克隆。
每個ArrayList例項都有一個容量,該容量是指用來儲存列表元素的陣列的大小。它總是至少等於列表的大小。隨著向ArrayList中不斷新增元素,其容量也自動增長。自動增長會帶來資料向新陣列的重新拷貝,因此,如果可預知資料量的多少,可在構造ArrayList時指定其容量。在新增大量元素前,應用程式也可以使用ensureCapacity操作來增加ArrayList例項的容量,這可以減少遞增式再分配的數量。
注意,此實現不是同步的。如果多個執行緒同時訪問一個ArrayList例項,而其中至少一個執行緒從結構上修改了列表,那麼它必須保持外部同步。
ArrayList繼承AbstractList,實現了List、 RandomAccess、Cloneable、Serializable介面, 為ArrayList內部是用一個陣列儲存元素值,相當於一個大小可變的陣列,也就是動態陣列。 由於ArrayList底層是陣列實現的,所以可以隨機訪問。
public class ArrayList<E> extends AbstractList<E>
implements List<E>, RandomAccess, Cloneable, java.io.Serializable
複製程式碼
(1)繼承和實現繼承了AbstractList,實現了List:ArrayList是一個陣列佇列,提供了相關的新增、刪除、修改、遍歷等功能。
實現RandmoAccess介面:即提供了隨機訪問功能。RandmoAccess是java中用來被List實現,為List提供快速訪問功能的在ArrayList中,我們即可以通過元素的序號快速獲取元素物件;這就是快速隨機訪問。
實現了Cloneable介面:即覆蓋了函式clone(),能被克隆。
實現java.io.Serializable介面:這意味著ArrayList支援序列化,能通過序列化去傳輸。
(2)執行緒安全
ArrayList不是執行緒安全的。建議在單執行緒中才使用ArrayList,而在多執行緒中可以選擇Vector或者CopyOnWriteArrayList。同樣,HashMap也是執行緒不安全的,如果需要併發訪問應該使用Hashtable(遺留類)或ConcurrentHashMap。
private static final int DEFAULT_CAPACITY = 10;//預設容量是10
複製程式碼
私有屬性:
/**
* The array buffer into which the elements of the ArrayList are stored.
* The capacity of the ArrayList is the length of this array buffer.
*/
private transient Object[] elementData;
/**
* The size of the ArrayList (the number of elements it contains).
*
* @serial
*/
private int size;
複製程式碼
elementData儲存ArrayList內的元素,size表示它包含的元素的數量。
有個關鍵字需要解釋:transient。
Java的serialization提供了一種持久化物件例項的機制。當持久化物件時,可能有一個特殊的物件資料成員,我們不想用serialization機制來儲存它。為了在一個特定物件的一個域上關閉serialization,可以在這個域前加上關鍵字transient。
經常在實現了 Serializable介面的類中能看見transient關鍵字。這個關鍵字並不常見。 transient關鍵字的作用是:阻止例項中那些用此關鍵字宣告的變數持久化;當物件被反序列化時(從原始檔讀取位元組序列進行重構),這樣的例項變數值不會被持久化和恢復。當某些變數不想被序列化,同是又不適合使用static關鍵字宣告,那麼此時就需要用transient關鍵字來宣告該變數。除了以上兩個成員變數,我們還需要掌握一個變數,它是
protected transient int modCount = 0;
複製程式碼
這個變數主要作用是防止在進行一些操作時,改變了ArrayList的大小,那將使得結果不可預測。
建構函式:
/**無參構造:
* Constructs an empty list with an initial capacity of ten.
*/
public ArrayList() {
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}
/**有參構造
* Constructs an empty list with the specified initial capacity.
*
* @param initialCapacity the initial capacity of the list
* @throws IllegalArgumentException if the specified initial capacity
* is negative
*/
public ArrayList(int initialCapacity) {
if (initialCapacity > 0) {
this.elementData = new Object[initialCapacity];
} else if (initialCapacity == 0) {
this.elementData = EMPTY_ELEMENTDATA;
} else {
throw new IllegalArgumentException("Illegal Capacity: "+
initialCapacity);
}
}
/**引數為集合的有參構造
* Constructs a list containing the elements of the specified
* collection, in the order they are returned by the collection's
* iterator.
*
* @param c the collection whose elements are to be placed into this list
* @throws NullPointerException if the specified collection is null
*/
public ArrayList(Collection<? extends E> c) {
elementData = c.toArray();
if ((size = elementData.length) != 0) {
// c.toArray might (incorrectly) not return Object[] (see 6260652)
if (elementData.getClass() != Object[].class)
elementData = Arrays.copyOf(elementData, size, Object[].class);
} else {
// replace with empty array.
this.elementData = EMPTY_ELEMENTDATA;
}
}
複製程式碼
常用的方法
boolean add(E e)
將指定的元素新增到此列表的尾部。
void add(int index, E element)
將指定的元素插入此列表中的指定位置
boolean addAll(Collection<? extends E> c)
按照指定 collection 的迭代器所返回的元素順序,將該 collection 中的所有元素新增到此列表的尾部。
boolean addAll(int index, Collection<? extends E> c)
從指定的位置開始,將指定 collection 中的所有元素插入到此列表中。
void clear()
移除此列表中的所有元素。
Object clone()
返回此 ArrayList 例項的淺表副本。
boolean contains(Object o)
如果此列表中包含指定的元素,則返回 true。
void ensureCapacity(int minCapacity)
如有必要,增加此 ArrayList 例項的容量,以確保它至少能夠容納最小容量引數所指定的元素數。
E get(int index)
返回此列表中指定位置上的元素。
int indexOf(Object o)
返回此列表中首次出現的指定元素的索引,或如果此列表不包含元素,則返回 -1。
boolean isEmpty()
如果此列表中沒有元素,則返回 true
int lastIndexOf(Object o)
返回此列表中最後一次出現的指定元素的索引,或如果此列表不包含索引,則返回 -1。
E remove(int index)
移除此列表中指定位置上的元素。
boolean remove(Object o)
移除此列表中首次出現的指定元素(如果存在)。
protected void removeRange(int fromIndex, int toIndex)
移除列表中索引在 fromIndex(包括)和 toIndex(不包括)之間的所有元素。
E set(int index, E element)
用指定的元素替代此列表中指定位置上的元素。
int size()
返回此列表中的元素數。
Object[] toArray()
按適當順序(從第一個到最後一個元素)返回包含此列表中所有元素的陣列。
void trimToSize()
將此 ArrayList 例項的容量調整為列表的當前大小。應用程式可以使用此操作來最小化 ArrayList 例項的儲存量。
複製程式碼
遍歷方式:
ArrayList支援3種遍歷方式
1.通過迭代器遍歷。即通過Iterator去遍歷
2.隨機訪問,通過索引值去遍歷,ArrayList實現了RandomAccess介面,它支援通過索引值去隨機訪問元素
3.for迴圈遍歷
遍歷ArrayList時,使用隨機訪問(即通過索引序號訪問)效率最高,而使用迭代器的效率相對較低。