Java学习历程17——利用泛型优化自定义动态数组
上次我们对自定义数组进行了第一次优化,解决了数组添加数据速度慢的问题,但是数组还存在缺陷:只能添加事先规定的一类数据,而不能根据需求添加不同类型的数据。今天我们利用泛型优化自定义动态数组。
要想数组可以添加所有类型的数据,就必须改变数组的类型。之前的知识告诉我们: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() {//默认数组的长度为10Arr = 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 |