在使用ArrayList時遇到一個很愚蠢的問題,想在大小為10的ArrayList的第5個位置插入10,結果抛異常。代碼示例如下
ArrayList<Integer> arr=new ArrayList<Integer>(10);
arr.add(5, 10);
異常為
Exception in thread "main" java.lang.IndexOutOfBoundsException: Index: 5, Size: 0
at java.util.ArrayList.rangeCheckForAdd(ArrayList.java:643)
at java.util.ArrayList.add(ArrayList.java:455)
很是郁悶,明明初始化了大小為10的空間,跑出的異常卻告訴我size為0。好吧,隻能直接點進去看源代碼了。版本1.7
public void add(int index, E element) {
rangeCheckForAdd(index);
ensureCapacityInternal(size + 1); // Increments modCount!!
System.arraycopy(elementData, index, elementData, index + 1,
size - index);
elementData[index] = element;
size++;
}
add方法,從異常看,是rangeCheckForAdd(index);這行,點進去,為rangeCheckForAdd(int index)這個函數
private void rangeCheckForAdd(int index) {
if (index > size || index < 0)
throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}
最終抛出去的異常内容來源為:
private String outOfBoundsMsg(int index) {
return "Index: "+index+", Size: "+size;
}
這就是開始那個異常 Exception in thread "main" java.lang.IndexOutOfBoundsException: Index: 5, Size: 0
接下來隻能看Size為啥為0了,源代碼:
/**
* The size of the ArrayList (the number of elements it contains).
*
* @serial
*/
private int size;
貌似真相大白了,size隻是此ArrayList所包含的元素個數,不是它的容量大小。
那麼怎麼辦呢?看ArrayList的帶參數構造函數
public ArrayList(int initialCapacity) {
super();
if (initialCapacity < 0)
throw new IllegalArgumentException("Illegal Capacity: "+
initialCapacity);
this.elementData = new Object[initialCapacity];
}
是以在構造函數裡,根本就沒有對size進行操作指派,是以size == 0。但是在add時他又強制檢查。是以隻好都add一遍,讓size遞增,然後去從新set這個值:
for (int i = 0; i < 10; i++) {
arr.add(0);
}
arr.set(5, 10);
但是有沒有感覺這種方法很愚蠢呢?
還是本來ArrayList就不适合做這種直接插入的操作吧!還沒有直接用數組操作友善。