import java.util.Arrays;
import java.util.Collection;
public class ArrayListTest {
Object[] no_initCapacity={};
private final int DEFAULT_CAPACITY=10;//初始化容量,当添加第一个元素之后
Object[] data;//底层的那个数组
private int size;
transient int modCount=0;
//数组的最大尺寸为2^31 = 2147483648,但是需要8bytes的存储大小表示数组的长度等元数据。所以数组的大小定义为Integer.MAX_VALUE - 8。
private static final int MAX_ARRAY_SIZE=Integer.MAX_VALUE-8;
public ArrayListTest() {//无参构造
this.data=no_initCapacity;
}
public ArrayListTest(int capacity) { //确定容量
if(capacity>0) {
data=new Object[capacity];
}
else if(capacity==0) {
this.data=no_initCapacity;
}
else {
throw new IllegalArgumentException("Illegal Capacity"+capacity);
}
}
public ArrayListTest(Collection c) {
data=c.toArray();
//如果这个集合不是空集合
if((size=data.length)!=0) {
//如果data不是Object[]类型,就将其转换为Object[]类型
if(data.getClass()!=Object[].class)
data=Arrays.copyOf(data,size,Object[].class);
}
else this.data=no_initCapacity;
}
public boolean isEmpty() {
return size==0;
}
public boolean contains(Object o) {
return indexOf(o)>=0;
}
public int indexOf(Object o) {
if(o==null) {
for(int i=0;i<size;i++) {
if(data[i]==null)
return i;
}
}else {
for(int i=0;i<size;i++) {
if (data[i].equals(o))
return i;
}
}
return -1;
}
public Object lastIndexOf(Object o) {
if(o==null) {
for(int i=size-1;i>=0;i++){
if(data[i]==null)
return i;
}
}
else {
for(int i=size-1;i>=0;i++) {
if(data[i]==o)
return i;
}
}
return -1;
}
public Object[] toArray() {
return Arrays.copyOf(data,size);
}
boolean add(Object e) {
//首先会判断data是否是空数组,如果是空数组,则最小容量为10,否则为size+1
//如果最小容量比目前数组的长度大,则需要扩容,否则不需要
//扩容的话是扩容为原数组的1.5倍,如果这个1.5倍小于最小容量,则直接是最小容量,如果这个1.5倍大于最大范围,
//则比较比较数组所需要的最小容量和最大容量的大小,如果比最大容量还大,就可以直接扩容为Integer.MAX_VALUE
ensureCapacityInternal(size+1);
data[size++]=e;
return true;
}
public int size() {
return size;
}
public Object get(int index) {
rangeCheck(index);
return data[index];
}
//将index下标的元素换为Object
public Object set(int index,Object object) {
rangeCheck(index);
Object oldElem=data[index];
data[index]=object;
return oldElem;
}
//按照元素下标删除
public Object remove(int index) {
//越界检查
rangeCheck(index);
Object o=data[index];
//size之后的元素都需要移动,
int numMoved=size-index-1;
if(numMoved>0) {
//从将index+1后numMoved长度的元素,复制到index后面去
System.arraycopy(data,index+1,data,index,numMoved);
}
//并把最后一个位置补成Null,size减少
data[--size]=null;
return o;
}
public void clear() {
for(int i=0;i<size;i++) {
data[i]=null;
}
//将元素个数置为0
size=0;
}
//越界检查
public void rangeCheck(int index) {
if(index>=size) {
throw new IndexOutOfBoundsException();
}
}
//判断是否需要扩容
public void ensureCapacityInternal(int minCapacity) {
ensureExplicitCapacity(calculateCapacity(data,size+1));
}
//看是否需要扩容
public void ensureExplicitCapacity(int minCapacity) {
modCount++;
//如果现在数组的长度,没有达到数组最小容量的要求,就需要扩容
if(minCapacity-data.length>0) {
grow(minCapacity);
}
}
//计算data数组所需要的最小容量,如果data是个空数组,最小容量就取默认容量10和size+1中的最大值,如果data不是个空数组,最小容量就是size+1
private int calculateCapacity(Object[] data,int minCapacity) {
if(data==no_initCapacity) {
return Math.max(DEFAULT_CAPACITY,minCapacity);
}
return minCapacity;
}
//扩容
public void grow(int minCapacity) {
int oldCapacity=data.length;
//新的容量是数组原来的长度+原来长度的一半,也就是新的容量是原来容量的1.5倍
int newCapacity=oldCapacity+(oldCapacity>>1);
//如果新的容量小于数组容量的最小要求,就将新的容量变为数组容量的最小要求
if(newCapacity-minCapacity<0) {
newCapacity=minCapacity;
}
//如果新的容量比最大的那个容量大
if(newCapacity-MAX_ARRAY_SIZE>0) {
//先计算最小数组容量与MAX_ARRAY_SIZE谁大,如果数组最小要求容量大,则将新的容量变为Integer.MAX_VALUE
newCapacity=hugeCapacity(minCapacity);
}
}
public int hugeCapacity(int minCapacity) {
if(minCapacity<0) //如果最小的容量小于0,则抛出异常
throw new OutOfMemoryError();
return (minCapacity>MAX_ARRAY_SIZE) ? Integer.MAX_VALUE:MAX_ARRAY_SIZE;
}
}
简单实现ArrayList底层(仅常用方法,注释详细)
于 2022-06-03 22:31:06 首次发布