用java实现一个ArrayList

通过查看ArrayList底层代码发现ArrayList有以下属性:

ArayList:

1、ArrayList如果初始化的时候没有指定容量则默认大小为10,如果容量不够则按照“newCapacity=oldCapaCity+(oldCapaCity >> 1)”算法进行扩容(原容量的1.5倍进行扩容);

2、ArrayList线程不安全,若要实现线程安全可以使用synchronized关键字或Collections.synchronizedList()方法初始化,如下

List list = Collections.synchronizedList(new ArrayList<>()); 或者使用:

3、ArrayList底层的数据结构是Object;类型的数组(Object[] elementData)所以它的很多方法都是按照数组的处理 方式进行的。

4、transient关键字修饰的变量表示不被序列化。

其中会使用到JDK中的System.arraycopy()方法,该方法可以把一个数组src复制成另外一个数组dest,是一个Native方法所以我们只关注传入参数的意义即可,源码如下:

    public static native void arraycopy(Object src,  int  srcPos,
                                        Object dest, int destPos,
                                        int length);

各个参数的含义:

1、Object src:原数组,就是我们需要复制的数组

2、int srcPos:表示从原数组的第几个下标开始

3、Object dest:表示复制完之后的数组(可以理解为一个新的数组,但是并不是新建一个数组)

4、int destPos:表示复制之后的数据从新数组的第几个下标开始存放

5、int length:表示从原数组中复制的长度。

示例如下:

public static void main(String[] args) {
        Object[] datas = new Object[20];
        datas[0] = "000";
        datas[1] = "111";
        datas[2] = "222";
        datas[3] = "333";
        datas[4] = "444";
        datas[5] = "555";
        datas[6] = "666";
        datas[7] = "777";
        datas[8] = "888";
        datas[9] = "999";
        // 从datas中的第2个数据开始复制,复制长度为8,然后从第三个下标开始存放在新数组datas中
        System.arraycopy(datas,2,datas,3,8);
        for (int i = 0; i < datas.length; i++) {
            System.out.print(datas[i]+" ");
        }
    }

执行结果:

000 111 222 222 333 444 555 666 777 888 999 null null null null null null null null null 

通过以上属性我们可以自己手动实现一个简单的ArrayList,代码如下:

public class MyArrayList {
    private Object[] elementData;
    private int size;
    private int defaultCapacity = 10;

    public int size() {
        return size;
    }

    public MyArrayList(){
        this(10);
    }

    public MyArrayList(int initCapacity) {
        if(initCapacity == 0){
            this.elementData = new Object[defaultCapacity];
        }else if (initCapacity > 0){
            this.elementData = new Object[initCapacity];
        }else{
            throw new IllegalArgumentException("初始化容量参数有误");
        }
    }
    // 获取某个节点的数据
    public Object get(int index){
        if(index < 0 || index > size){
            throw new IndexOutOfBoundsException();
        }
        return elementData[index];
    }

    // 往数组中添加元素
    public void add(Object object) {
        ensureCapacity(size +1);
        elementData[size] = object;
        size++;
    }

    // 数组扩容
    public void ensureCapacity(int size){
        int currentCapacity = elementData.length;
        if (size > currentCapacity) {
            int newCapacity = currentCapacity << 1 + currentCapacity;
            Object[] newElementData = new Object[newCapacity];
            System.arraycopy(elementData,0,newElementData,0,currentCapacity);
            elementData = newElementData;
        }
    }
    // 往指定位置添加元素
    public void add(int index, Object data){
        if(index < 0 || index > size){
            throw new IndexOutOfBoundsException();
        }
        ensureCapacity(size+1); // 扩容
        System.arraycopy(elementData,index,elementData,index+1,size-index);
        elementData[index] = data;
        size++;
    }

    // 修改指定位置的数据
    public Object set(int index,Object data){
        if(index < 0 || index > size){
            throw new IndexOutOfBoundsException();
        }
        Object oldData = elementData[index];
        elementData[index] = data;
        return oldData;
    }

    // 删除指定位置上的元素
    public Object delete(int index){
        if(index < 0 || index > size){
            throw new IndexOutOfBoundsException();
        }
        Object oldData = elementData[index];
        if(index == size) {
            elementData[index] = null;
        }else{
            int copyLength = size-index-1;
            System.arraycopy(elementData,index+1,elementData,index,copyLength);
        }
        size --;
        return oldData;
    }

}

测试类:

class MyTest{
    public static void main(String[] args) {
        MyArrayList myArrayList = new MyArrayList();
        for (int i = 0; i < 20; i++) {
            myArrayList.add(i+"aaaa");
        }
        MyTest.showData(myArrayList);
        System.out.println("指定位置添加数据--------------------------");
        myArrayList.add(3,"sdssd");
        MyTest.showData(myArrayList);
        System.out.println("修改指定位置的数据--------------------------");
        System.out.println(myArrayList.set(5,"测试"));
        MyTest.showData(myArrayList);
        System.out.println("删除指定位置的数据--------------------------");
        System.out.println(myArrayList.delete(2));
        MyTest.showData(myArrayList);

    }

    private static void showData(MyArrayList myArrayList){
        for (int i = 0; i < myArrayList.size(); i++) {
            System.out.print(myArrayList.get(i) +" ");
        }
        System.out.println("");
    }

}

执行结果:

0aaaa 1aaaa 2aaaa 3aaaa 4aaaa 5aaaa 6aaaa 7aaaa 8aaaa 9aaaa 10aaaa 11aaaa 12aaaa 13aaaa 14aaaa 15aaaa 16aaaa 17aaaa 18aaaa 19aaaa 
指定位置添加数据--------------------------
0aaaa 1aaaa 2aaaa sdssd 3aaaa 4aaaa 5aaaa 6aaaa 7aaaa 8aaaa 9aaaa 10aaaa 11aaaa 12aaaa 13aaaa 14aaaa 15aaaa 16aaaa 17aaaa 18aaaa 19aaaa 
修改指定位置的数据--------------------------
4aaaa
0aaaa 1aaaa 2aaaa sdssd 3aaaa 测试 5aaaa 6aaaa 7aaaa 8aaaa 9aaaa 10aaaa 11aaaa 12aaaa 13aaaa 14aaaa 15aaaa 16aaaa 17aaaa 18aaaa 19aaaa 
删除指定位置的数据--------------------------
2aaaa
0aaaa 1aaaa sdssd 3aaaa 测试 5aaaa 6aaaa 7aaaa 8aaaa 9aaaa 10aaaa 11aaaa 12aaaa 13aaaa 14aaaa 15aaaa 16aaaa 17aaaa 18aaaa 19aaaa 

猜你喜欢

转载自blog.csdn.net/u013804636/article/details/107791815