ArrayList的简单实现

ArrayList是List接口的一个可变大小的数组的实现
ArrayList的内部是使用一个Object对象数组来存储元素的
初始化ArrayList的时候,可以指定初始化容量的大小,如果不指定,就会使用默认大小,为10
当添加一个新元素的时候,首先会检查容量是否足够添加这个元素,如果够就直接添加,如果不够就进行扩容,扩容为原数组容量的1.5倍
当删除一个元素的时候,会将数组右边的元素全部左移

ArrayList使用的存储的数据结构是Object的对象数组,因为是数组,所有具有数组普遍的优点,比如随机存取快,删除操作比较慢等。

这里尝试着实现一个基本的CustomArrayList,主要参考Java8的ArrayList实现。

定义ArrayList类

import java.util.*;

public class CustomArrayList<E> {
    private static final int DEFAULT_CAPACITY = 10;

    private static final Object[] EMPTY_ELEMENTDATA = {};
    private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};

    transient Object[] elementData;
    private int size;

    public CustomArrayList(int initialCapacity) {
        if (initialCapacity > 0) {
            this.elementData = new Object[initialCapacity];
        } else if (initialCapacity == 0) {
            this.elementData = EMPTY_ELEMENTDATA;
        } else {
            throw new IllegalArgumentException("Illegal Capacity: " + initialCapacity);
        }
    }

    public CustomArrayList() {
        this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
    }
}

其中最基本的是elementData属性,在类里面的所有数组都是存储在这个属性里面。如果创建CustomArrayList的时候,没有确定数组大小,则初始化elementData为空;如果创建CustomArrayList已经确定了数组大小,那么new一个指定大小的数组即可。

add 操作

CustomArrayList添加元素也是比较简单的,首先预判断elementData的分配的空间长度是否能够新添加一个元素,如果可以,那么将元素添加在elementData有效元素的末尾便可;如果elementData的分配的空间长度不足以添加一个元素,那么便在原来空间长度的基础上添加原空间长度的一半大小。

public boolean add (E e) {
    ensureCapacityInternal(size + 1);
    elementData[size++] = e;
    return true;
}

private void ensureCapacityInternal(int minCapacity) {
    if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
        minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
    }

    if (minCapacity - elementData.length > 0) {
        grow(minCapacity);
    }
}

private void grow(int minCapacity) {
    int oldCapacity = elementData.length;
    int newCapacity = oldCapacity + (oldCapacity >> 1);
    if (newCapacity - minCapacity < 0) {
        newCapacity = minCapacity;
    }
    elementData = Arrays.copyOf(elementData, newCapacity);
}

remove操作

删除CustomArrayList中的元素可以分为两种,一种是删除指定下标的元素,另一种是删除指定值的元素。

删除指定下标的元素

首先判断给定的下标是否合法,如果不合法,那么抛出异常;如果合法,那么只需要使用指定下标后面的元素依次覆盖掉指定下标的值便可。

public E remove(int index) {
    if (index >= size) {
        throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + this.size);
    }

    E oldValue = (E)elementData[index];

    int numMoved = size - index - 1;

    if (numMoved > 0) {
        System.arraycopy(elementData, index + 1, elementData, index, numMoved);
    }

    elementData[--size] = null;

    return oldValue;
}

删除指定值的元素

这种方式的删除需要遍历一次数组,当找到数组中的指定值使,记录下标,然后使用该下标后面的值依次覆盖掉该下标的值便可。

public boolean remove(Object o) {
    if (o == null) {
        for (int index = 0; index < size; index++) {
            if (elementData[index] == null) {
                fastRemove(index);
                return true;
            }
        }
    } else {
        for (int index = 0; index < size; index++) {
            if (o.equals(elementData[index])) {
                fastRemove(index);
                return true;
             }
         }
     }
     return false;
}

private void fastRemove(int index) {
    int numMoved = size - index - 1;
    if (numMoved > 0) {
        System.arraycopy(elementData, index + 1, elementData, index, numMoved);
    }
    elementData[--size] = null;
}

indexOf操作

首先判断传进来的值是否为null,如果是null,那么则判断CustomArrayList中是否夹杂着null元素,如果是的话,返回该元素的下标;如果并没有夹杂null元素,则返回-1

如果传进来的对象值不为null,那么遍历一遍CustomArrayList,将找到的元素值的下标返回便可。

public int indexOf(Object o) {
    if (o == null) {
         for (int i = 0; i < size; i++) {
            if (elementData[i] == null) {
                return i;
            }
        }
    } else {
        for (int i = 0; i < size; i++) {
            if (o.equals(elementData[i])) {
                return i;
            }
        }
     }
    return -1;
}

验证

public void getAll () {
    for (int i = 0; i < size; i++) {
        System.out.println(elementData[i]);
    }
}

getAll方法主要是为了打印出目前数组中所有元素进行验证使用

public static void main(String[] args) {
    CustomArrayList arrayList = new CustomArrayList(5);
    arrayList.add(0);
    arrayList.add(1);
    arrayList.add(8);
    arrayList.add(9);
    arrayList.getAll();

    arrayList.remove(1);
    Boolean flag = arrayList.remove(Integer.valueOf(8));
    System.out.println(flag);

    arrayList.getAll();
    int index = arrayList.indexOf(null);
    System.out.println(index);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值