public class ArrayList<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, java.io.Serializable
底層使用數組
private transient Object[] elementData;
java 的transient關鍵字為我們提供了便利,你只需要實現Serilizable介面,將不需要序列化的屬性前添加關鍵字transient,
序列化對象的時候,這個屬性就不會序列化到指定的目的地中。
transient關鍵字只能修飾變數,而不能修飾方法和類。一個靜態變數不管是否被transient修飾,均不能被序列化
private static final int DEFAULT_CAPACITY = 10;
預設的初始容量為10
有三個建構函式,
一。自訂長度的 public ArrayList(initialCapacity)
二。預設長度10, public ArrayList()
三。構造一個包含指定 collection 的元素的列表,這些元素是按照該 collection 的迭代器返回它們的順序排列的
public ArrayList(Collection<? extends E> c) { elementData = c.toArray(); size = elementData.length; // c.toArray might (incorrectly) not return Object[] (see 6260652) if (elementData.getClass() != Object[].class) elementData = Arrays.copyOf(elementData, size, Object[].class); }
重點聊一下這個吧,這邊我看到有人說不懂為什麼這邊要判斷
是因為toArray返回的不一定是一個object的,
如:List<String> strList= Arrays.asList("abc")
Object[] strList=stringList.toArray();
System.out.println(strList.getClass());
這邊返回的是class java.lang.String
判斷以後複製數組
延伸:System.arraycopy() 和 Arrays.copyOf()的區別
數組擴容
private void ensureExplicitCapacity(int minCapacity) { modCount++; // overflow-conscious code if (minCapacity - elementData.length > 0) grow(minCapacity); } private void grow(int minCapacity) { // overflow-conscious code int oldCapacity = elementData.length; int newCapacity = oldCapacity + (oldCapacity >> 1); if (newCapacity - minCapacity < 0) newCapacity = minCapacity; if (newCapacity - MAX_ARRAY_SIZE > 0) newCapacity = hugeCapacity(minCapacity); // minCapacity is usually close to size, so this is a win: elementData = Arrays.copyOf(elementData, newCapacity); } private static int hugeCapacity(int minCapacity) { if (minCapacity < 0) // overflow throw new OutOfMemoryError(); return (minCapacity > MAX_ARRAY_SIZE) ? Integer.MAX_VALUE : MAX_ARRAY_SIZE; }
grow中有這樣的一行
int newCapacity = oldCapacity + (oldCapacity >> 1);
位移運算子:>>(帶符號右移),
表示的是新的數組擴容為原來的1.5倍的大小
但是有一個限制,表示的是要分配的數組的最大大小;
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
如果超過這個大小,會報OutOfMemoryError的異常。那麼就要使用MAX_ARRAY_SIZE的長度
在方法裡面有一個modCount++,
這個屬性是AbstractList中的
protected transient int modCount = 0;
表示的是這個list的結構已經被修改過的次數; 具體解釋
ArrayList 還給我們提供了將底層數組的容量調整為當前列表儲存的實際元素的大小的功能。
它可以通過 trimToSize() 方法來實現。該方法可以最小化 ArrayList 執行個體的儲存量
public void trimToSize() { modCount++; if (size < elementData.length) { elementData = Arrays.copyOf(elementData, size); } }