分析以下例子:java
1 import java.util.Arrays; 2 import java.util.List; 3 4 5 public class Test { 6 public static void main(String[] args) { 7 Integer[] a = {0,1,2,3,4,5,6}; 8 List<Integer> c = Arrays.asList(a); 9 for (Integer integer : c) { 10 System.out.println(integer); 11 } 12 c.add(7); 13 c.remove(0); 14 15 } 16 }
打印結果爲:數組
0 1 2 3 4 5 6 Exception in thread "main" java.lang.UnsupportedOperationException at java.util.AbstractList.add(AbstractList.java:151) at java.util.AbstractList.add(AbstractList.java:89) at com.cys.collections.MapTest.main(MapTest.java:14)
查看Arrays.asList() 底層實現:spa
public static <T> List<T> asList(T... a) { return new ArrayList<T>(a); }
實現一樣是ArrayList ! But,再向下看:code
文件名: Arrays$ArrayList.class 代表ArrayList是一個Arrays 類的內部類,與咱們平時使用的ArrayList 並不一樣;對象
它繼承了一個抽象類AbstractList並使用該抽象類的add 和 remove方法:blog
public boolean add(E o) { add(size(), o); return true; } public void add(int index, E element) { throw new UnsupportedOperationException(); } public E remove(int index) { throw new UnsupportedOperationException(); }
所有拋出了一個UnsupportedOperationException 異常,說明該list不支持改變它長度的狀況。繼承
可是一樣是數組實現的直接 new 的 ArrayList爲何就能夠呢?內存
讓咱們看一看它的add 代碼:ci
1 public boolean add(E o) { 2 ensureCapacity(size + 1); // Increments modCount!! 3 elementData[size++] = o; 4 return true; 5 }
public boolean addAll(Collection<? extends E> c) { Object[] a = c.toArray(); int numNew = a.length; ensureCapacity(size + numNew); // Increments modCount System.arraycopy(a, 0, elementData, size, numNew); size += numNew; return numNew != 0; }
這兩個方法裏面的第一行,均是確信當前容量是否能容下新增長的對象。element
public void ensureCapacity(int minCapacity) { modCount++; int oldCapacity = elementData.length; if (minCapacity > oldCapacity) { Object oldData[] = elementData; int newCapacity = (oldCapacity * 3)/2 + 1; if (newCapacity < minCapacity) newCapacity = minCapacity; elementData = (E[])new Object[newCapacity]; System.arraycopy(oldData, 0, elementData, 0, size); } }
此方法裏,一旦發現容量不足,會自動擴充容量,新的大小是
int newCapacity = (oldCapacity * 3)/2 + 1
再經過拷貝方法,新new一個數組。
remove 就很簡單了,就是單純的刪去一個位置上的數據,而後把後面的數據依次向前挪。
因此 new ArrayList 能夠 remove 和add 。
題外話:
咱們看到ArrayList 的擴充是原來的1.5倍+1,因此爲了不頻繁擴充帶來的擴充損耗,應當儘量大的new ArrayList的初始長度,
可是太大的話,若是數據增加很慢,就會佔用不少沒用的內存,因此這個長度仍是須要根據業務的實際狀況,合理申請。
http://www.cnblogs.com/caoyusongnet/