本次我们要实现的目标是自定义一种数据结构,可以帮助我们管理下标、增删改查、自动扩容。
一,数据类型基础知识
java中有两种数据类型:基本数据类型和引用数据类型。
1,基本数据类型
基本数据类型只有8种,可以按照如下分类:
①整数类型:byte、short、int、long
②浮点类型:float、double
③字符类型:char
④布尔类型:boolean
2,引用数据类型
引用数据类型分三种:类(class)、接口(interface)、数组(array)。
简单来说,所有非基本数据类型都属于引用数据类型。
public class Main{
public static void main(String[] args){
//基本数据类型
int i=1;
double d=1.2;
//引用数据类型
String str="helloworld";
}
}
3,基本数据类型和引用数据类型的区别
①在方法中定义的非全局基本数据类型变量的具体内容是存储在栈中的。
②引用数据类型变量其具体内容是存放在堆中的,而栈中存放的是其具体内容所在的内存地址。
二,自定义数据结构
1,首先我们先创建一个大小固定为10的数组,并且用size记录数组中存放的元素个数。
package com.yzd1211.MyArray;
public class MyArray {
//数组长度
int length=10;
//数组中存储了的数据长度
int size=0;
//定义一个初始数组
int[] array = new int[length];//length为数组长度 元素值默认为0
}
2,增加具体功能:添、删、改、查
//添加方法 将num数据增加到数组中
public void add(int num) {
//扩容 一旦添加的数据量大于数组的长度 对数组进行扩容
array[size++]=num;
}
//删除数据 根据索引下标删除
public void deleteIndex(int index) {
array[index]=0;
//删除之后数据留空 将后续的数据向前补充
}
//删除数据 根据具体数删除
public void deleteNum(int num) {
int i;
for(i=0;i<array.length;i++) {
if(array[i]==num) {
array[i]=0;
}
}
}
//该数据 将指定位置的数据修改成指定值
public void change(int index,int num) {
array[index]=num;
}
//获取数据 根据下标获取数据
public int getNum(int index) {
return array[index];
}
//获取下标 根据具体数据获取数据的下标
public int getIndex(int num) {
int i=0;
for(;i<length;i++) {
if(array[i]==num) {
return i;
}
}
return i;
}
3,功能完善
在增加了上述功能之后发现我们的自定义数据结构存在一些不足,比如当我们删除某些数后数组中该位置就空缺了,如何将后面的数据向前补齐呢?如果我们存储的数据个数超过了数组定义的长度数组如何自动扩容呢?
①删除之后自动补齐
当我们删除第i个数后,就要依次从第i+1个数开始,每个数往前移一个位置,这就实现了自动补齐的功能。
将上述删除代码修改如下:
//删除数据 根据索引下标删除
public void deleteIndex(int index) {
array[index]=0;
//删除之后数据留空 将后续的数据向前补充
for(int i=index;i<array.length;i++) {
if((i+1)<array.length) {
array[i]=array[i+1];
}
}
}
//删除数据 根据具体数删除
public void deleteNum(int num) {
int i;
for(i=0;i<array.length;i++) {
if(array[i]==num) {
array[i]=0;
//每删除完一个数据之后立即将后续数据补上
for(int j=i;j<array.length;j++) {
if((j+1)<array.length) {
array[j]=array[j+1];//j+1是数组的最后一个数字
}
}
}
}
}
②自动扩容
我们定义的数组长度是10,数组下标从0开始计数,当存储完第10个数后size++=10,满足判断条件size>=length,于是创建一个新数组ExArray,大小为20,将原来数组中的元素全部给到新数组之后,将新数组ExArray的地址赋给原数组array(对数组名操作即对数组地址操作),原数组array就指向了一个大小为20的数组,这样当添加第11个数的时候就是向扩大了的array中添加,不会对其他方法产生影响。
//添加方法 将num数据增加到数组中
public void add(int num) {
//扩容 一旦添加的数据量大于数组的长度 对数组进行扩容
array[size++]=num;//??? array长度为length 当添加数据长度大于数组长度时 为何不报错
if(size>=length) {
//最后存完size还加了一次,数组下标超出了一个,与数组最大长度相等了 故需要扩容
int[] ExArray=new int[length*2];
for(int i=0;i<array.length;i++) {
ExArray[i]=array[i];
}
array=ExArray;
}
}
4,测试
//主函数
public static void main(String[] args) {
MyArray myarray = new MyArray();
for(int i=0;i<13;i++) {
myarray.add(i);//存入0~13 测试扩容功能
}
myarray.deleteIndex(4);//删除下标为4的元素
myarray.deleteIndex(5);//删除下标为5的元素 执行上两行后删除的是数字6
myarray.deleteIndex(7);//删除下标为7的元素 执行上两行后删除的是数字9
myarray.deleteNum(2);//删除数据2
myarray.deleteNum(1);//删除数据1
for(int i=0;i<13;i++) {
System.out.print(" "+myarray.getNum(i));//将存入的数据输出
}
}
得到的输出为:
测试成功!