Java学习历程17——利用泛型优化自定义动态数组

发布于:2025-08-31 ⋅ 阅读:(20) ⋅ 点赞:(0)

上次我们对自定义数组进行了第一次优化,解决了数组添加数据速度慢的问题,但是数组还存在缺陷:只能添加事先规定的一类数据,而不能根据需求添加不同类型的数据。今天我们利用泛型优化自定义动态数组。

要想数组可以添加所有类型的数据,就必须改变数组的类型。之前的知识告诉我们:Object是Java中所有类的父类,如果把数组类型设置为Object,那么数组就可以容纳任何的数据。这里需要注意一个细节:理论上Object类型的数组只能保存引用类型,但所有的基本类型都不是引用类型,之所以能将基本类型的数据添加进Object数组中,是因为添加时基本数据类型会自动转变成对应的包装类。综上所述,我们只需要将数组类型和方法中数据data的类型改成Object就可以添加任何类型的数据了!

效果如下图:

但是我们又遇到了一个问题:如果一个数组什么类型的数据都能随意添加进去,数组就会变得很凌乱,不利于数据的分类保存,所以我们希望能够让数组根据输入的内容只能添加一种类型,这是就要用到泛型的内容。

我们需要在类ArrayList后面加上一个尖括号<>,表示该类为泛型,里面需要填写名字,一般命名为T、E、K、V等(需要有语义)。数组类型依然为Object不变,但需要把方法的参数里的data类型改为对应的名字,表示只能是这个类型的数据添加到数组中。

代码

//尖括号表示泛型,目的是实现只能添加一种元素的功能。
    //尖括号里的数据类型只能是包装类,不能是基本数据类型
public class ArrayList<E> {
    public Object[] Arr;
    private static int length = 10;
    //定义一个变量保存数组中的有效数据个数
    private int size;

    //使用构造方法写两个数组的使用方法
    public ArrayList() {
        //默认数组的长度为10
        Arr = new Object[length];
    }

    public ArrayList(int len) {
        //手动定义数组的初始长度
        Arr = new Object[length];
    }

    //末尾添加数据
    public void add(E data) {
        //判断是否需要扩容
        if (size == Arr.length) {
            //两倍扩容数组
            Object[] nArr = new Object[Arr.length * 2];
            for (int i = 0; i < Arr.length; i++) {
                nArr[i] = Arr[i];
            }
            //更改内存地址
            Arr = nArr;
        }
        //数据添加到末尾
        Arr[size] = data;
        size++;
    }

    //插入数据
    public void add(E data, int index) {
        //判断数组是否需要扩容
        if (size == Arr.length) {
            //两倍扩容数组
            Object[] nArr = new Object[Arr.length * 2];
            //从index 位置开始,把后面的数据往后移动
            for (int i = 0; i < index; i++) {
                nArr[i] = Arr[i];
            }
            for (int i = index; i < Arr.length; i++) {
                nArr[i + 1] = Arr[i];
            }
            Arr = nArr;
            Arr[index] = data;
            size++;
        } else if (size < Arr.length) {
            for (int i = index; i < size; i++) {
                Arr[i + 1] = Arr[i];
            }
            Arr[index] = data;
            size++;
        }
    }

    //获取指定位置的数据
    public E get(int index) {
        if (index < 0 || index > Arr.length) {
            System.out.println("下标越界!!!");
            return null;
        } else {
            return (E)Arr[index];
        }
    }

    //移除指定位置的数据
    public E remove(int index) {
        Object removeData = Arr[index];
            for (int i = index; i < size; i++) {
                Arr[i] = Arr[i + 1];
            }
            size--;
        return (E)removeData;
    }

    //移除指定的数据
    public boolean removes(E data) {
        boolean gs=false;
            for (int i = 0; i < Arr.length; i++) {
                if (Arr[i]==data ) {
                    remove(i);
                    gs= true;
                }
            }
        return gs;
    }
    //获得数组的长度
    public int getSize() {
        return Arr.length;
    }


    public static void main(String[] args) {
        ArrayList<Integer> list = new ArrayList<>();
        //添加整型数据
        list.add(1);
        list.add(2);
        list.add(3);
        list.add(5);
        list.add(6);
        list.add(7);
        list.add(8);
        list.add(9);
        list.add(10);
        list.add(11);
        list.add(4, 3);
        list.removes(2);
        for (int i = 0; i < list.size; i++) {
            System.out.print(list.get(i) + " ");
        }

    }
}

这样,我们就能实现只能在数组中添加同一种数据的功能了!

补充知识

1、泛型

在Java中,我们用尖括号<>表示泛型,可以把添加到动态数组(集合)中的类型参化,里面需要输入引用类型或者基本类型对应的包装类。将基本数据类型变成包装类的过程叫做装箱

作用:限制必须是同类型的数据才能添加到同一个集合对象中。

2、基本数据类型及其对应的包装类

基本数据类型 对应的包装类
byte(整型) Byte
short(整型) Short
int(整型) Integer
long(整型) Long
float(浮点型) Float
double(浮点型) Double
char(字符) Character
boolean(布尔型) Boolean


网站公告

今日签到

点亮在社区的每一天
去签到