欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

自定义简单实现ArrayList

程序员文章站 2022-03-21 17:04:50
...

ArrayList是基于数组实现的。

首先明白两个数组的方法

  • System.arraycopy()方法

源码如下

自定义简单实现ArrayList

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

自定义简单实现ArrayList

  • 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增加,容量增长的参数

 
相关标签: ArrayList