【Java集合框架库】ArrayList源码实现

ArrayList源码实现

具体的ArrayList类的特点及详细介绍,请参考ArrayList类。在这里,仅仅是自己重新实现ArrayList相关操作的方法。

属性

我们都知道,ArrayList是通过模拟数组实现的动态变化的集合,因此它的底层实现仍然是数组。

private Object[] element; //以数组模拟ArrayList
private int size; //有效个数
private static final int DEFAULT_SIZE = 10; //初始化大小
private static final Object[] EMPTY_ELEMENT = {}; //定义一个空数组,用于初始化集合
构造方法
/**
 * 为防止集合实例化对象后长时间不使用,导致空间浪费,
 * 因此初始化时将集合初始化为空数组,待添加第一个元素时将数组大小扩容为默认大小
 */
public MyArrayList(){
    this.element = EMPTY_ELEMENT;
}
public MyArrayList(int DEFAULT_CAPACITY){
    this.element = new Object[DEFAULT_CAPACITY];
}
辅助操作
  • 判断数组中是否还有空闲位置,若没有则进行扩容操作。
/**
 * 判断数组中是否还有空闲位置,若没有则进行扩容操作
 */
public void ensureCapacityInternal(int size){
    if(size >= element.length){
        grow(size);
    }
}
  • 扩容操作:
    • 如果还未插入任何元素,此时数组为空数组,数组大小为0,需要进行初始化操作。
    • 若只是数组已满,则进行1.5倍扩容操作。
/**
 * 扩容操作:
 *      如果还未插入任何元素,此时数组为空数组,数组大小为0,需要进行初始化操作
 *      若只是数组已满,则进行1.5倍扩容操作
 */
public void grow(int size) {
    if (size == 1) {
        element = new Object[DEFAULT_SIZE];
        return;
    }
    int oldSize = element.length;
    int newSize = oldSize + (oldSize >> 1);
    element = Arrays.copyOf(element,newSize); //TODO:记得重新将新数组赋给element
}
  • 判断传入的下标是否合法,若不合法则抛出异常。
/**
 * 判断传入的下标是否合法,若不合法则抛出异常
 */
public void rangeCheck(int index){
    if(index < 0 || index >= size){
        throw new IndexOutOfBoundsException();
    }
}
插入操作
  • 在数组已存在元素的末尾进行操作操作。
/**
 * 插入操作
 *      在数组已存在元素的末尾进行操作操作
 */
public boolean add(T value){
    ensureCapacityInternal(size+1); //判断数组是否已满,否则进行扩容操作
    element[size++] = value;
    return true;
}
  • 在指定下标处插入元素。
/**
 * 插入操作
 *      在指定下标处插入元素
 */
public boolean add(int index, T value){
    rangeCheck(index); //判断下标是否合法
    ensureCapacityInternal(size+1); //判断数组是否已满,否则进行扩容操作
    System.arraycopy(element,index,element,index+1,size-index); //进行元素移动
    element[index] = value; //在该下标处插入元素
    size++;
    return true;
}
删除操作
  • 删除指定下标处的元素。
/**
 * 删除元素
 *      删除指定下标处的元素
 */
public void remove(int index){
    rangeCheck(index); //判断下标是否合法
    System.arraycopy(element,index+1,element,index,size-index-1); //进行元素移动
    element[--size] = null; //此时末尾元素依然存在,将其赋空并使size减一
}
  • 删除指定元素。
/**
 * 删除元素
 *      删除指定元素
 */
public void remove(T value){
    if(value == null){
        for(int index = 0;index < size;index++){
            if(element[index] == null){
                remove(index);
                return;
            }
        }
    }else {
        for(int index = 0;index < size;index++){
            if(element[index].equals(value)){
                remove(index);
                return;
            }
        }
    }
}
更改元素
  • 更改指定下标处的元素。
/**
 * 更改元素
 *      更改指定下标处的元素
 */
public void set(int index, T newValue){
    rangeCheck(index); //判断下标是否合法
    element[index] = newValue; //将新元素赋值给该下标处
}
获取元素
  • 获取指定下标处的元素。
/**
 * 获取元素
 *      获取指定下标处的元素
 */
public Object get(int index){
    rangeCheck(index); //判断下标是否合法
    return element[index]; //返回下标元素
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值