自定义简单实现ArrayList

ArrayList是基于数组实现的。

首先明白两个数组的方法

  • System.arraycopy()方法

源码如下

src:源对象
srcPos:源数组中的起始位置
dest:目标数组对象
destPos:目标数据中的起始位置
length:要拷贝的数组元素的数量

  • Arrays.copyOf()方法

数组拷贝时调用的是本地方法 System.arraycopy() ;
Arrays.copyOf()方法返回的数组是新的数组对象,原数组对象仍是原数组对象,不变,该拷贝不会影响原来的数组。

/**
 *1.构造函数,如果调用无参构造,则初始值默认为10,
 *2.add方法
 *      2.1 先判断是否需要扩容
 *          2.1.1扩容后数组的大小设置为是1.5倍
 *          2.1.2需要判断扩容后的容量是否充足
 *          2.1.3如果最小容量比新容量要小,则采用初始容量minCapacity
 *      2.2 在进行添加
 *3.get方法
 *      3.1先判断是否超过实际数据长度
 *4.remove方法
 *      4.1数组需要移动的次数
 *      4.2从后往前覆盖
 *      4.3将原来实际数据的数组下标的最后一位置空
 *      4.4返回删除元素
 * @param <E>
 */
public class ArrayListDemo<E> {
    //默认初始值
    private static final int DEFAULT_CAPACITY = 10;
    //保存ArrayList中的数组
    private Object[] elementData;
    //数据实际的数量
    private int size;

    public ArrayListDemo() {
        //默认初始值
        this(DEFAULT_CAPACITY);
    }

    public ArrayListDemo(int initialCapacity) {
        if(initialCapacity > 0){
            elementData = new Object[initialCapacity];
        }
    }

    //添加方法
    public void add(E e){
        //判断是否需要扩容
        isNeedExport(size+1);
        elementData[size++] = e;
    }

    //添加方法
    public void add(int index,E e){
        //先判断是否超过实际数据长度
        checkIndex(index);
        //判断是否需要扩容
        isNeedExport(size+1);
        //数组需要移动的次数
        int removeNum = size - index;
        System.arraycopy(elementData,index,elementData,index+1,removeNum);
        elementData[index] = e;
        size++;
    }

    //获取数据
    public E get(int index){
        //先判断是否超过实际数据长度
        checkIndex(index);
        return (E) elementData[index];
    }

    //
    public E remove(int index){
        E e = get(index);
        //数组需要移动的次数
        int removeNum = elementData.length - index - 1;
        if(removeNum > 0){
            //从后往前覆盖
            System.arraycopy(elementData,index+1,elementData,index,removeNum);
        }
        //将原来实际数据的数组下标的最后一位置空
        elementData[--size] = null;
        //返回删除元素
        return e;
    }

    //检测数组下标
    private void checkIndex(int index) {
        if(index >= size){
            throw new IndexOutOfBoundsException("数组越界啦!");
        }
    }

    //扩容方法
    private void isNeedExport(int minCapacity) {
        //如果实际数量达到了数组的长度,则需要扩容
        if(size == elementData.length){
            //扩容前数组的大小
            int oldCapacity = elementData.length;
            //扩容后数组的大小,就是1.5倍
            int newCapacity = oldCapacity + (oldCapacity >> 1);
            //如果原数组大小为1,1.5倍扩容后还是1,所以,需要判断扩容后的容量是否充足
            if(oldCapacity > newCapacity){
                //如果最小容量比新容量要小,则采用初始容量minCapacity
                newCapacity = minCapacity;
            }
            elementData = Arrays.copyOf(elementData,newCapacity);
        }
    }

    public int getSize() {
        return size;
    }

}

 

Vector

Vector是线程安全的,但是性能比ArrayList要低。

ArrayList,Vector主要区别为以下几点:

(1)Vector是线程安全的,源码中有很多的synchronized可以看出,而ArrayList不是。导致Vector效率无法和ArrayList相比

(2)ArrayList和Vector都采用线性连续存储空间,当存储空间不足的时候,ArrayList默认增加为原来的50%,Vector默认增加为原来的一倍

(3)Vector可以设置capacityIncrement,而ArrayList不可以,从字面理解就是capacity容量,Increment增加,容量增长的参数

 

猜你喜欢

转载自blog.csdn.net/u014034683/article/details/88973095