Java简单易懂线性表之泛型顺序表实现

1.线性表的定义

线性表,从名字上你就能感觉到,是具有像线 样的性质的表。

线性表(linear list)是n个具有相同特性的数据元素的有限序列。 线性表是一种在实际中广泛使用的数据结构,常见的线性表:顺序表、链表、栈、队列、字符串

线性表在逻辑上是线性结构,也就说是连续的一条直线。但是在物理结构上并不一定是连续的,线性表在物理上存储时,通常以数组和链式结构的形式存储

在这里插入图片描述

这里需要强调几个关键的地方:

首先它是一个 序列 也就是说,元素之间是有顺序的,若元素存在多个,则第 一个 元素无前驱,最后一个元素无后继,其他每个元素都有且只有 一个 前驱和后继
然后,线性表强调是有限的,在计算机中处理的对象都是有限的,那种无限的数列,只存在于数学的概念中。

如果用数学语言来进行定义可如下:
若将线性表记为 (a1, …, ai-1 , ai, ai+1, …, an),则表中 ai-1 领先于先于 ai;ai 领先于 ai+1:称 ai-1是 ai 的直接前驱元素,ai+1 是 ai 的直接后继元素。当 i=1,2,…,n-1 时,ai 有且仅有一个直接后继,当 i=2,3,…,n时,ai有且仅有一个直接前驱。如图所示:
在这里插入图片描述
所以线性表元素的个数 n(n≥0) 定义为线性表的长度,当 n=0 时,称为空表。

在非空表中的每个数据元素都有一个确定的位置,如 ai 是第 一个数据元素, an最后一个数据元素,ai 是第 i个 数据元素,称 i 为数据元素 ai 在线性表中的位序。

2.线性表的抽象数据类型

我们已经知道了线性表的定义,现在我们来分析 线性表应该有些什么样的操作呢?
模拟的是String类型数据的顺序表【也可以使用泛型,可以支持更多的数据】

public class myArrayList {
    
    
    private int[] array;
    private int size;
    private static int capacity = 5;

    public myArrayList() {
    
    
        this.array = new String[capacity];
        this.size = capacity;
    }

    private void addLast(String e){
    
    }
    private void addIndex(int index, String e){
    
    }
    private String remove(int index){
    
    return null;}
    private boolean remove(String e){
    
    return false;}
    private String get(int index){
    
    return null;}
    private String set(int index, String e){
    
    return null;}
    private boolean contains(String e){
    
    return false;}
    private int indexOf(String e){
    
    return -1;}
    private int lastIndexOf(String e){
    
    return -1;}
    private void clear(){
    
    }
    private int size(){
    
    return this.size;}
    private boolean isEmpty(){
    
    return this.size == 0;}
}

3.线性表的顺序存储结构

3.1 顺序存储定义

线性表的顺序存储结构,指的是用一段地址连续的存储单元依次存储线性表的数据元素,示意图如下:
在这里插入图片描述

3.2 顺序存储方式

    private String[] array;
    private int size;
    private static int capacity = 5;

线性表的顺序存储结构就是在内存中找了块地儿,把一定内存空间结占了,然后把 相同数据类型的数据元素 依次存放在这块空地中。。既然线性表的每个数据元素的类型都相同,所以可以用 Java 语言(其 也相同)的一维数组来实现顺序存储结构, 即把第 1 个数据元素存到数组下标为 0 的位置中,接着把线性表相邻的元素存储在数组中相邻的位置。
这里,我们就发现描述顺序存 结构需要 三个属性:

  1. 存储空间的起始位置:数组 array ,它的存储位置就是存储空间的存储位置。
  2. 线性表的最大存储容量:数组长度capacity
  3. 线性表的当前长度:size

3.3数据长度和线性表长度的区别

注意哦,这里有两个概念"数组的长度"和"续性表的长度"需要区分一下。

数组的长度是存放线性表的存储空间的长度,存储分配后这个量是一般是不变的。有个别同学可能会问 “ 数组的大小一定不可以变吗?我怎么看到有书中谈到可以动态分配的维数组 “ 。是的, 般高级语言 比如 C++都可以用编程 段实现动态分配数组,不过这会带来性能上的损耗。

线性表的长度是线性表中数据元素的个数,随着线性表插入和删除操作的进行,这个量是变化的。

在任意时刻,线性表的长度应该小于等于数组的长度。

3.4 地址计算方法

由于我们数数都是从 1 开始数的,线性表的定义也不能免俗,起始也是 1,可是大部分语言中的数组却是从 0 开始第 1个下标的,于是线性表的第 i个 元素是要存储在数组下标为 i-1 的位置,即数据元素的序号和存放它的数组下标之间存在对应关系
在这里插入图片描述
假设占用的是 c个 存储单元,那么线性表 i+l 个数据元素的存储位置和第 i个数据元素的存储位置满足下列关系 (LOC 表示获得存储位置的函数)

LOC(ai+1) = LOC(ai)+c
所以对于第 i个数据元素 ai 的存储位置可以由 a1 推算得出:
LOC(ai) = LOC(a1)+(i-1)*c

在这里插入图片描述
通过这个公式,你可以随时算出线性表中任意位置的地址,不管它是第 一个 还是最后一个,都是相同的时间。那么我们对每个线性表位置的存入或者取出数据,对于计算机来说都是相等的时间,也就是一个常数,因此用我们算法中学到的时间复杂度的概念来说,它的存取时间性能为 0(1) 。我们通常把具有这一特点的存储结构称为随机存取结构

4.顺序表的CRUD

4.1 add【增加元素】

    // 尾插
    private void addLast(String e) {
    
    
        if (this.size >= capacity) {
    
    
            realloc();
        }
        this.array[this.size++] = e;
    }

    // 任意位置添加
    private void addIndex(int index, String e) throws mArrayListOutOfIndexRange {
    
    
        if (index <= 0 || index - 1 > this.size) {
    
    
            throw new mArrayListOutOfIndexRange(index + "下标越界");
        } else {
    
    
            if (this.size >= capacity) {
    
    
                realloc();
            }
            for (int i = this.size - 1; i >= index; i--) {
    
    
                this.array[i + 1] = this.array[i];
            }
            this.array[index - 1] = e;
            ++this.size;
        }
    }
    @Override
    public String toString() {
    
    
        StringBuffer stringBuffer = new StringBuffer("[");
        for (int i = 0; i < this.size; i++) {
    
    
            stringBuffer.append(this.array[i]);
            if (i < this.size - 1) {
    
    
                stringBuffer.append(", ");
            }
        }
        stringBuffer.append("]");
        String result = stringBuffer.toString();
        return result;
    }

    private static void testAddLast() {
    
    
        myArrayList arrayList = new myArrayList();
        for (int i = 1; i <= 10; i++) {
    
    
            arrayList.addLast(String.valueOf(i));
        }
        System.out.println("testAddLast(): " + arrayList);
    }

    private static void testAddIndex() throws mArrayListOutOfIndexRange {
    
    
        myArrayList arrayList = new myArrayList();
        for (int i = 1; i <= 10; i++) {
    
    
            arrayList.addIndex(i, String.valueOf(i));
        }
        System.out.println("testAddIndex(): " + arrayList);
    }

4.2 remove【删除元素】

    // 按下标删除
    private String remove(int index) throws mArrayListOutOfIndexRange {
    
    
        if (index <= 0 || index - 1 > this.size) {
    
    
            throw new mArrayListOutOfIndexRange(index + "越界");
        } else {
    
    
            /*
             index-1 是为了消除下标起始 0 开始
             this.size-1 是因为一处一个元素后数组长度要减一
             */
            String result = this.array[index - 1];
            for (int i = index - 1; i < this.size - 1; i++) {
    
    
                this.array[i] = this.array[i + 1];
            }
            --this.size;
            return result;
        }
    }

    // 按值删除【删除第一次出现的元素】
    private boolean remove(String e) {
    
    
        for (int i = 0; i < this.size - 1; i++) {
    
    
            if (this.array[i].equals(e)) {
    
    
                for (int j = i; j < this.size - 1; j++) {
    
    
                    this.array[j] = this.array[j + 1];
                }
                --this.size;
                return true;
            }
        }
        return false;
    }
    
    public static void testRemoveIndexAndValue() throws mArrayListOutOfIndexRange {
    
    
        myArrayList arrayList = new myArrayList();
        for (int i = 1; i <= 10; i++) {
    
    
            arrayList.addLast(String.valueOf(i));
        }
        boolean result1 = arrayList.remove(String.valueOf(6));
        String result2 = arrayList.remove(10);
        System.out.println("testRemoveIndexAndValue(): " + result1);
        System.out.println("testRemoveIndexAndValue(): " + result2);
        System.out.println("testRemoveIndexAndValue(): " + arrayList);
    }

4.3 get【获取元素值】

    private String get(int index) throws mArrayListOutOfIndexRange {
    
    
        if (index - 1 < 0 || index - 1 > this.size) {
    
    
            throw new mArrayListOutOfIndexRange(index + "越界");
        } else {
    
    
            return this.array[index - 1];
        }
    }
    
    private static void testGet() throws mArrayListOutOfIndexRange {
    
    
        myArrayList arrayList = new myArrayList();
        for (int i = 1; i <= 10; i++) {
    
    
            arrayList.addLast(String.valueOf(i));
        }
        String result = arrayList.get(1);
        System.out.println("testGet(): " + result);
    }

4.4 set【设置元素值】

private void set(int index, String e) throws mArrayListOutOfIndexRange {
    
    
        if (index - 1 < 0 || index - 1 > this.size) {
    
    
            throw new mArrayListOutOfIndexRange(index + "越界");
        } else {
    
    
            this.array[index - 1] = e;
        }
    }

    private static void testSet() throws mArrayListOutOfIndexRange {
    
    
        myArrayList arrayList = new myArrayList();
        for (int i = 1; i <= 10; i++) {
    
    
            arrayList.addLast(String.valueOf(i));
        }
        arrayList.set(1, String.valueOf(11));
        System.out.println("testSet():" + arrayList);
    }

4.5 contains【元素是否存在】

    private boolean contains(String e) {
    
    
        for (int i = 0; i < this.size; i++) {
    
    
            if (this.array[i].equals(e)) {
    
    
                return true;
            }
        }
        return false;
    }

    private static void testContains() {
    
    
        myArrayList arrayList = new myArrayList();
        for (int i = 1; i <= 10; i++) {
    
    
            arrayList.addLast(String.valueOf(i));
        }
        System.out.println("testContains(): " + arrayList.contains(String.valueOf(1)));
    }
    private static void testIndexOf() {
    
    
        myArrayList arrayList = new myArrayList();
        for (int i = 1; i <= 10; i++) {
    
    
            arrayList.addLast(String.valueOf(i));
        }
        System.out.println(arrayList.indexOf("testIndexOf(): " + String.valueOf(1)));
    }

4.6 indexOf【正序查下标】

    private int indexOf(String e) {
    
    
        for (int i = 0; i < this.size; i++) {
    
    
            if (this.array[i].equals(e)) {
    
    
                return i + 1;
            }
        }
        return -1;
    }

	    private static void testIndexOf() {
    
    
        myArrayList arrayList = new myArrayList();
        for (int i = 1; i <= 10; i++) {
    
    
            arrayList.addLast(String.valueOf(i));
        }
        System.out.println(arrayList.indexOf("testIndexOf(): " + String.valueOf(1)));
    }

4.7 lastIndexOf【逆序查下标】

    private int lastIndexOf(String e) {
    
    
        for (int i = this.size - 1; i >= 0; i--) {
    
    
            if (this.array[i].equals(e)) {
    
    
                return i + 1;
            }
        }
        return -1;
    }

	private static void testLastIndexOf() {
    
    
        myArrayList arrayList = new myArrayList();
        for (int i = 1; i <= 10; i++) {
    
    
            arrayList.addLast(String.valueOf(i));
        }
        arrayList.addLast(String.valueOf(1));
        System.out.println("testLastIndexOf(): " + arrayList.lastIndexOf(String.valueOf(1)));
    }

4.8 clear【清空】

	private void clear() {
    
    
        this.size = 0;
    }

    private static void testClear() {
    
    
        myArrayList arrayList = new myArrayList();
        for (int i = 1; i <= 10; i++) {
    
    
            arrayList.addLast(String.valueOf(i));
        }
        arrayList.clear();
        System.out.println("testClear(): " + arrayList);
    }

4.9 size【获取长度】

   private int size() {
    
    
        return this.size;
    }

    private static void testSize() {
    
    
        myArrayList arrayList = new myArrayList();
        for (int i = 1; i <= 10; i++) {
    
    
            arrayList.addLast(String.valueOf(i));
        }
        System.out.println("testSize(): " + arrayList.size);
    }

4.10 isEmpty【是否为空】

	private boolean isEmpty() {
    
    
	        return this.size == 0;
	    }
	
	private static void testIsEmpty() {
    
    
	        myArrayList arrayList = new myArrayList();
	        for (int i = 1; i <= 10; i++) {
    
    
	            arrayList.addLast(String.valueOf(i));
	        }
	        System.out.println("testIsEmpty(): " + arrayList.isEmpty());
	    }

4.11 越界异常类

class mArrayListOutOfIndexRange extends Exception {
    
    
    /*
    由于 mArrayListOutOfIndexRange 继承的是 Exception 受查异常所以需要手动解决问题
                                  如果继承的是 RuntiemException 非受查异常,所以不需要手动解决
    这里继承的是 受查异常,所以需要在调用到这个异常的函数都需要手动抛出异常类
    */
    public mArrayListOutOfIndexRange(String message) {
    
    
        super(message);
    }
}

5.完整代码【myArrayList.java】

class mArrayListOutOfIndexRange extends Exception {
    
    
    /*
    由于 mArrayListOutOfIndexRange 继承的是 Exception 受查异常所以需要手动解决问题
                                  如果继承的是 RuntiemException 非受查异常,所以不需要手动解决
    这里继承的是 受查异常,所以需要在调用到这个异常的函数都需要手动抛出异常类
    */
    protected mArrayListOutOfIndexRange(String message) {
    
    
        super(message);
    }
}

public class myArrayList {
    
    
    private String[] array;
    private int size;
    private static int capacity = 5;

    private myArrayList() {
    
    
        this.array = new String[capacity];
        this.size = 0;
    }

    // 扩容
    private void realloc() {
    
    
        capacity *= 2;
        String[] newArray = new String[capacity];
        for (int i = 0; i < this.size; i++) {
    
    
            newArray[i] = this.array[i];
        }
        // this.array 的引用指向 newArray 后之前引用指向内容由于缺少引用,就会被垃圾回收机制(GC)回收
        this.array = newArray;
    }

    // 尾插
    private void addLast(String e) {
    
    
        if (this.size >= capacity) {
    
    
            realloc();
        }
        this.array[this.size++] = e;
    }

    // 任意位置添加
    private void addIndex(int index, String e) throws mArrayListOutOfIndexRange {
    
    
        if (index <= 0 || index - 1 > this.size) {
    
    
            throw new mArrayListOutOfIndexRange(index + "下标越界");
        } else {
    
    
            if (this.size >= capacity) {
    
    
                realloc();
            }
            for (int i = this.size - 1; i >= index; i--) {
    
    
                this.array[i + 1] = this.array[i];
            }
            this.array[index - 1] = e;
            ++this.size;
        }
    }

    // 按下标删除
    private String remove(int index) throws mArrayListOutOfIndexRange {
    
    
        if (index <= 0 || index - 1 > this.size) {
    
    
            throw new mArrayListOutOfIndexRange(index + "越界");
        } else {
    
    
            /*
             index-1 是为了消除下标起始 0 开始
             this.size-1 是因为一处一个元素后数组长度要减一
             */
            String result = this.array[index - 1];
            for (int i = index - 1; i < this.size - 1; i++) {
    
    
                this.array[i] = this.array[i + 1];
            }
            --this.size;
            return result;
        }
    }

    // 按值删除【删除第一次出现的元素】
    private boolean remove(String e) {
    
    
        for (int i = 0; i < this.size - 1; i++) {
    
    
            if (this.array[i].equals(e)) {
    
    
                for (int j = i; j < this.size - 1; j++) {
    
    
                    this.array[j] = this.array[j + 1];
                }
                --this.size;
                return true;
            }
        }
        return false;
    }

    private String get(int index) throws mArrayListOutOfIndexRange {
    
    
        if (index - 1 < 0 || index - 1 > this.size) {
    
    
            throw new mArrayListOutOfIndexRange(index + "越界");
        } else {
    
    
            return this.array[index - 1];
        }
    }

    private void set(int index, String e) throws mArrayListOutOfIndexRange {
    
    
        if (index - 1 < 0 || index - 1 > this.size) {
    
    
            throw new mArrayListOutOfIndexRange(index + "越界");
        } else {
    
    
            this.array[index - 1] = e;
        }
    }

    private boolean contains(String e) {
    
    
        for (int i = 0; i < this.size; i++) {
    
    
            if (this.array[i].equals(e)) {
    
    
                return true;
            }
        }
        return false;
    }

    private int indexOf(String e) {
    
    
        for (int i = 0; i < this.size; i++) {
    
    
            if (this.array[i].equals(e)) {
    
    
                return i + 1;
            }
        }
        return -1;
    }

    private int lastIndexOf(String e) {
    
    
        for (int i = this.size - 1; i >= 0; i--) {
    
    
            if (this.array[i].equals(e)) {
    
    
                return i + 1;
            }
        }
        return -1;
    }

    private void clear() {
    
    
        this.size = 0;
    }

    private int size() {
    
    
        return this.size;
    }

    private boolean isEmpty() {
    
    
        return this.size == 0;
    }

    @Override
    public String toString() {
    
    
        StringBuffer stringBuffer = new StringBuffer("[");
        for (int i = 0; i < this.size; i++) {
    
    
            stringBuffer.append(this.array[i]);
            if (i < this.size - 1) {
    
    
                stringBuffer.append(", ");
            }
        }
        stringBuffer.append("]");
        String result = stringBuffer.toString();
        return result;
    }

    private static void testAddLast() {
    
    
        myArrayList arrayList = new myArrayList();
        for (int i = 1; i <= 10; i++) {
    
    
            arrayList.addLast(String.valueOf(i));
        }
        System.out.println("testAddLast(): " + arrayList);
    }

    private static void testAddIndex() throws mArrayListOutOfIndexRange {
    
    
        myArrayList arrayList = new myArrayList();
        for (int i = 1; i <= 10; i++) {
    
    
            arrayList.addIndex(i, String.valueOf(i));
        }
        System.out.println("testAddIndex(): " + arrayList);
    }

    private static void testRemoveIndexAndValue() throws mArrayListOutOfIndexRange {
    
    
        myArrayList arrayList = new myArrayList();
        for (int i = 1; i <= 10; i++) {
    
    
            arrayList.addLast(String.valueOf(i));
        }
        boolean result1 = arrayList.remove(String.valueOf(6));
        String result2 = arrayList.remove(10);
        System.out.println("testRemoveIndexAndValue(): " + result1);
        System.out.println("testRemoveIndexAndValue(): " + result2);
        System.out.println("testRemoveIndexAndValue(): " + arrayList);
    }

    private static void testGet() throws mArrayListOutOfIndexRange {
    
    
        myArrayList arrayList = new myArrayList();
        for (int i = 1; i <= 10; i++) {
    
    
            arrayList.addLast(String.valueOf(i));
        }
        String result = arrayList.get(1);
        System.out.println("testGet(): " + result);
    }

    private static void testSet() throws mArrayListOutOfIndexRange {
    
    
        myArrayList arrayList = new myArrayList();
        for (int i = 1; i <= 10; i++) {
    
    
            arrayList.addLast(String.valueOf(i));
        }
        arrayList.set(1, String.valueOf(11));
        System.out.println("testSet():" + arrayList);
    }

    private static void testContains() {
    
    
        myArrayList arrayList = new myArrayList();
        for (int i = 1; i <= 10; i++) {
    
    
            arrayList.addLast(String.valueOf(i));
        }
        System.out.println("testContains(): " + arrayList.contains(String.valueOf(1)));
    }

    private static void testIndexOf() {
    
    
        myArrayList arrayList = new myArrayList();
        for (int i = 1; i <= 10; i++) {
    
    
            arrayList.addLast(String.valueOf(i));
        }
        System.out.println(arrayList.indexOf("testIndexOf(): " + String.valueOf(1)));
    }

    private static void testLastIndexOf() {
    
    
        myArrayList arrayList = new myArrayList();
        for (int i = 1; i <= 10; i++) {
    
    
            arrayList.addLast(String.valueOf(i));
        }
        arrayList.addLast(String.valueOf(1));
        System.out.println("testLastIndexOf(): " + arrayList.lastIndexOf(String.valueOf(1)));
    }

    private static void testClear() {
    
    
        myArrayList arrayList = new myArrayList();
        for (int i = 1; i <= 10; i++) {
    
    
            arrayList.addLast(String.valueOf(i));
        }
        arrayList.clear();
        System.out.println("testClear(): " + arrayList);
    }

    private static void testSize() {
    
    
        myArrayList arrayList = new myArrayList();
        for (int i = 1; i <= 10; i++) {
    
    
            arrayList.addLast(String.valueOf(i));
        }
        System.out.println("testSize(): " + arrayList.size);
    }

    private static void testIsEmpty() {
    
    
        myArrayList arrayList = new myArrayList();
        for (int i = 1; i <= 10; i++) {
    
    
            arrayList.addLast(String.valueOf(i));
        }
        System.out.println("testIsEmpty(): " + arrayList.isEmpty());
    }

    public static void main(String[] args) throws mArrayListOutOfIndexRange {
    
    
        // 放置测试用例
    }
}

6.部分逻辑思路解析

6.1 插入算法思路

在这里插入图片描述

  1. 如果指定插入位置不合理,抛出异常
  2. 如果线性表长度大于等于数组长度,则动态增加容量
  3. 从最后一个元素开始向前遍历到第 index 个位置,分别将它们都向后移动一个位置
  4. 将要插入元素填入位置 index 处
  5. 表长加 1

6.2 删除算法思路

在这里插入图片描述

  1. 如果删除位置 index 不合理,抛出异常
  2. 取出删除元素
  3. 从删除元素位置 index 开始遍历到最后一个元素,分别将它们都向前移动一格位置
  4. 表长减 1

7. 线性表顺序存储结构的优缺点

现在我们来分析一下,插入和删除的 间复杂度。

先来看最好的情况,如果元素要插入到最后一个位置或者删除最后一个元素,此时时时间复杂度为 O(1) ,因为不需要移动元素的,就如同来了一个新人要正常排队,当然是排在最后,如果此时他又不想排了,那么他一个人离开就好了,不影响任何人。

最坏的情况呢,如果元素要插入到第一个位置或者删除第一个元素,此时时间复杂度是多少? 那就意味着要移动所有的元素向后或者向前,所以这个时间复杂度为O(n)

至于平均的情况,由于元素插入到第 i 个位置,或删除第 i 个元素 需要移动 n-i 个元素 根据概率原理,每个位置插入或删除元素的可能性是相同的,也就说位置靠前,移动元素多,位置靠后,移动元素少。最终平均移动次数和最中间的那个元素移动次数相等,为(n-1)/2。

时间复杂度的推导,可以得出,平均时间复杂度还是 O(n)

这说明什么? 线性表的顺序存储结构,在存,读数据时,不管是 置,时间复杂度都是 O(1) 而插入或删除时,时间复杂度都是 O(n) 。这就说明:它比较适合元素个数不大变化,而更多是存取数据的应用。当然,它的优缺点还不只这些…

优点 缺点
无须为表中元素之间的逻辑关系而增加额外的存储空间 插入和删除操作需要移动大量元素
可以快速地存取表中任意位置的元素 造成存储空间的“碎片”
当线性表长度变化较大的时候,难以确定存储空间的容量

8.泛型顺序表

仅提供稍微难一点的增加和删除操作,其余操作就不演示代码和测试用例

package dataStructure;

import java.util.Arrays;

/**
 * Created by: cxf
 * Description:
 * User: 19696
 * Date: 2021-08-30
 * Time: 15:40
 */
class genericsArrayListIndexOutOfRange extends RuntimeException {
    
    
    protected genericsArrayListIndexOutOfRange(String message) {
    
    
        super(message);
    }
}

public class genericsArrayList<T> {
    
    
    private T[] elem;
    private int usedSize;
    private static int intCapacity = 5;

    private genericsArrayList() {
    
    
        this.elem = (T[]) new Object[intCapacity];
        this.usedSize = 0;
    }

    // 扩容
    private void realloc() {
    
    
        intCapacity *= 2;
        this.elem = Arrays.copyOf(this.elem, intCapacity);
    }

    // 增
    private void addLast(T e) {
    
    
        if (this.usedSize >= intCapacity) {
    
    
            realloc();
        }
        this.elem[this.usedSize++] = e;
    }

    private void addIndex(int index, T e) {
    
    
        if (this.usedSize >= intCapacity) {
    
    
            realloc();
        }
        if (index > this.usedSize) {
    
    
            throw new genericsArrayListIndexOutOfRange(index + "越界");
        } else {
    
    
            for (int i = this.usedSize - 1; i >= index; i++) {
    
    
                this.elem[i + 1] = this.elem[i];
            }
            this.elem[index] = e;
            ++this.usedSize;
        }
    }

    // 删
    private void remove(int index) {
    
    
        if (index > this.usedSize) {
    
    
            throw new genericsArrayListIndexOutOfRange(index + "越界");
        } else {
    
    
            for (int i = index; i < this.usedSize - 1; i++) {
    
    
                this.elem[i] = this.elem[i + 1];
            }
            --this.usedSize;
        }
    }

    private void remove(T e) {
    
    
        for (int i = 0; i < this.usedSize; i++) {
    
    
            if (e.equals(this.elem[i]) || this.elem[i] == e) {
    
    
                for (int j = i; j < this.usedSize - 1; j++) {
    
    
                    this.elem[j] = this.elem[j + 1];
                }
                --this.usedSize;
                break;
            }
        }
    }

    @Override
    public String toString() {
    
    
        StringBuffer stringBuffer = new StringBuffer("[");
        for (int i = 0; i < this.usedSize; i++) {
    
    
            if (i < this.usedSize - 1) {
    
    
                stringBuffer.append(this.elem[i] + ", ");
            }
        }
        stringBuffer.append(this.elem[this.usedSize - 1] + "]");
        return stringBuffer.toString();
    }

    private static void testAdd() {
    
    
        genericsArrayList<Integer> arrayList1 = new genericsArrayList<>();
        for (int i = 0; i < 10; i++) {
    
    
            arrayList1.addLast(i);
        }
        System.out.println("addLast():" + arrayList1);
        genericsArrayList<Integer> arrayList2 = new genericsArrayList<>();
        for (int i = 0; i < 10; i++) {
    
    
            arrayList2.addIndex(i, i);
        }
        System.out.println("addIndex():" + arrayList2);
    }

    private static void testRemove() {
    
    
        genericsArrayList<Integer> arrayList = new genericsArrayList<>();
        for (int i = 0; i < 10; i++) {
    
    
            arrayList.addLast(i);
        }
        for (int i = 0; i < 5; i++) {
    
    
            arrayList.remove(Integer.valueOf(i));
        }
        System.out.println(arrayList);
    }

    public static void main(String[] args) {
    
    
        // 放置测试用例
    }
}

猜你喜欢

转载自blog.csdn.net/weixin_45364220/article/details/119983113