自己实现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());
}
}