自己實現ArrayList,最簡單的java的GclArrayList
說明:只實現了簡單的增刪改查,爲了新手讀源碼方便。
代碼如下:
package jdk;
import java.util.AbstractList;
import java.util.Arrays;
import java.util.ConcurrentModificationException;
public class GclArrayList<E> extends AbstractList<E> {
//默認數組容量10
private static final int default_capacity = 10;
//空元素數據數組
private static final Object[] empty_elementdata = {};
//默認空元素數據數組
private static final Object[] defaultcapacity_empty_elementdata = {};
//元素數據數組,實際操作的數組
private transient Object[] elementData;
//允許的最大數組容量
private static final int max_array_size = Integer.MAX_VALUE - 8;
private int size;
public GclArrayList(){
this.elementData = defaultcapacity_empty_elementdata;
}
//巨大容量,超過了最大數組長度max_array_size,返回Int最大值21億多
private static int hugeCapacity(int minCapacity){
//int值溢出,則會成爲負數,拋出內容溢出錯誤。
if (minCapacity < 0){
throw new OutOfMemoryError();
}
return (minCapacity > max_array_size) ? Integer.MAX_VALUE : max_array_size;
}
//擴容,很多方法的前置方法
private void grow(int minCapacity){
//當前元素數組長度
int oldCapacity = elementData.length;
//加一半容量
int newCapacity = oldCapacity + (oldCapacity >> 1);
if(newCapacity - minCapacity < 0){
newCapacity = minCapacity;
}
if (newCapacity - max_array_size > 0){
newCapacity = hugeCapacity(minCapacity);
}
//將擴容後的數組賦給元素數組
elementData = Arrays.copyOf(elementData,newCapacity);
}
//確保外部容量能放下新元素
private void ensureExplicitCapacity(int minCapacity){
//擴容次數
modCount ++;
if (minCapacity - elementData.length > 0){
grow(minCapacity);
}
}
//確保內部容量足夠
private void ensureCapacityInternal(int minCapacity){
if (elementData == defaultcapacity_empty_elementdata){
minCapacity = Math.max(default_capacity,minCapacity);
}
ensureExplicitCapacity(minCapacity);
}
//增加元素
public boolean add(E e){
ensureCapacityInternal(size + 1);
elementData[size++] = e;
return true;
}
//越界信息
private String outOfBoundsMsg(int index){
return "Index: "+index+",Size: "+size;
}
//範圍檢查,訪問數組下標必須不大於數組中的元素個數
private void rangeCheck(int index){
if (index >= size){
throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}
}
E elementData(int index) {
return (E) elementData[index];
}
//刪除元素
public E remove(int index){
//範圍檢查
rangeCheck(index);
//修改次數
modCount++;
E oldValue = elementData(index);
int numMoved = size - index - 1;
if (numMoved > 0)
System.arraycopy(elementData, index+1, elementData, index,
numMoved);
elementData[--size] = null; // clear to let GC do its work
return oldValue;
}
//修改元素
public E set(int index,E element){
rangeCheck(index);
E oldValue = elementData(index);
elementData[index] = element;
return oldValue;
}
//查詢元素
@Override
public E get(int index) {
rangeCheck(index);
return elementData(index);
}
//同步檢查修改
private void checkForComdification(){
if (GclArrayList.this.modCount != this.modCount){
throw new ConcurrentModificationException();
}
}
@Override
public int size() {
checkForComdification();
return this.size;
}
}
測試代碼:
package jdk;
public class ArrayListMain {
public static void main(String[] args) {
GclArrayList gclArrayList = new GclArrayList();
gclArrayList.add("1asdfdsfds");
gclArrayList.add(2);
gclArrayList.add("sfdsdfdsfsfff");
System.out.println(gclArrayList.toString());
System.out.println(gclArrayList.size());
System.out.println(gclArrayList.get(2));
gclArrayList.remove(1);
System.out.println(gclArrayList.toString());
gclArrayList.set(1,"改變之後的");
System.out.println(gclArrayList.toString());
}
}