Java代码实现ArrayList

ArrayList结构图

在这里插入图片描述

ArrayList特点

ArrayList的优点如下:

  • ArrayList 底层以数组实现,是一种随机访问模式。因此查找的时候非常快。
  • ArrayList 在顺序添加一个元素的时候非常方便。

ArrayList 的缺点如下:

  • 删除元素的时候,需要做一次元素复制操作。如果要复制的元素很多,那么就会比较耗费性能。
  • 插入元素的时候,也需要做一次元素复制操作,缺点同上。

适用场景:ArrayList 比较适合顺序添加、随机访问的场景。

Java代码实现ArrayList

注意点:注意数组下标越界问题
public class MyArrayList<E> {
    
    

    // 数组长度
    private int size;
    // 数组已存数据的大小
    private int index;
    // 声明数组
    private E dadaArr[];

    // 构造函数完成初始化
    public MyArrayList(int size){
    
    
        this.size = size;
        this.index = 0;
        this.dadaArr = (E[]) new Object[size];
    }

    // 插入元素
    public void add(int loc,E data){
    
    
        // ArrayList需要保证数据的连续性所以插入元素需要保证loc小于等于index,否则报错
        if(loc > index){
    
    
            System.out.println("java.lang.IndexOutOfBoundsException");
            return;
        }
        // 判断越界问题:已存数据大小需要小于数组长度才可以插入,否则触发扩容机制后插入
        if(index ++ < size){
    
    
            // 插入数据时前面的数据不动,后面的数据需要往后依次移动1
            for (int i = size -1; i > loc ; i--) {
    
    
                // 将loc位置后的所有元素往后移动
                dadaArr[i] = dadaArr[i -1];
            }
            dadaArr[loc] = data;
        }else{
    
        // 否则走扩容逻辑,通过位运算进行1.5倍扩容
            increaseCapacity(loc,data);
        }
    }

    // 移除元素(这里只写了根据loc移除对应元素,其余根据数据值移除逻辑类似,自行补充)
    public E remove(int loc){
    
    
        // 同理需要判断是否loc越界
        if(loc > index){
    
    
            System.out.println("java.lang.IndexOutOfBoundsException");
            return null;
        }
        E removeData = dadaArr[loc];
        // 由于移除元素不需要考虑越界问题,所以这里直接将loc后的元素前移1
        for (int i = loc; i < dadaArr.length; i++) {
    
    
            // 判断是否到了最后一个位置,到了就将最后一个位置的元素置为null
            if(i != dadaArr.length -1){
    
    
                dadaArr[i] = dadaArr[i + 1];
            }else{
    
    
                dadaArr[i] = null;
            }

        }
        // 每次移除一个元素已存数据的大小减1
        index--;
        return removeData;
    }

    // 根据loc获取元素
    public E get(int loc){
    
    
        return dadaArr[loc];
    }

    // 更新根据loc元素
    public void update(int loc,E data){
    
    
        dadaArr[loc] = data;
    }

    // 扩容方法 1.5倍扩容 (注意,其缩容逻辑类似,就不贴出)
    private void increaseCapacity(int loc,E data){
    
    
        int oldCapacity = dadaArr.length;
        // 1 + 0.5 倍
        int newCapacity = oldCapacity + (oldCapacity >> 1);
        E[] newDataArr = (E[])new Object[newCapacity];
        // 将之前数组中的数据复制到扩容后的新数组中去
        for (int i = 0; i < dadaArr.length; i++) {
    
    
            newDataArr[i] = dadaArr[i];
        }
        // 扩容数据转移后再走插入数据流程,后面的数据需要往后依次移动1
        for (int i = newDataArr.length - 1; i > loc ; i--) {
    
    
            // 将loc位置后的所有元素往后移动
            newDataArr[i] = newDataArr[i -1];
        }
        newDataArr[loc] = data;
        // 最后将新的数组对象赋给dadaArr并且将size修改为扩容后的size
        dadaArr = newDataArr;
        size = newDataArr.length;
    }

    // 打印方法
    public void print(){
    
    
        System.out.println("index:" + index);
        for(int i = 0 ; i < index ; i++){
    
    
            System.out.print(dadaArr[i] + " ");
        }
        System.out.println();
    }
    
    // 测试
    public static void main(String[] args) {
    
    
        MyArrayList<String> myArrList = new MyArrayList<>(4);
        myArrList.add(0,"a");
        myArrList.add(1,"b");
        myArrList.add(2,"c");
        myArrList.add(3,"d");
        myArrList.print();
        myArrList.add(3,"f");
        myArrList.add(3,"g");
        String remove = myArrList.remove(3);
        System.out.println("remove---->"+remove);
        System.out.println(myArrList);
    }

}

猜你喜欢

转载自blog.csdn.net/qq_40436854/article/details/120484921