简单实现ArrayList底层(仅常用方法,注释详细)

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;
    }

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值