@题目:设置一个类, 命名为 MyList
类中包含属性:Object[] element
需要实现如下的方法:
- 增加方法 add : 可以向数组属性中依次存储 Object,数组内容
存满时,需实现动态扩容(详解在下面)。 - 删除方法 remove :可以根据数据或下标,从数组属性中删除
Object 数据,删除后,数组后续元素需前移。 - 查询方法 get :方法传入下标,返回数组中指定下标的数据。
当前存储数据量 size : 获取当前存储的有效数据长度
动态扩容详解:无需真正增加原数组的容量,只用将原内容复制到新
的大数组,然后让原数组名称重新等于大数组即可。由于原数组数据在堆中,
失去引用会被 GC 自动回收。
思路:由于根据题意本身数组内可以存在null,为了避免在前移数组内容和在尾部追加数据取代null时,不能精确定位数组最后一个非null内容的位置(用length来取尾可能出现末尾n个都已经是null,倒数第n+1个需要消掉的情况。)所以应该先编写size来确定有效长度。
int size(){
int k = 0;
//设置有效长度计数器
for (int i = 0;i<element.length;i++){
//检索数组
if (element[i]==null){
//假如数组当前下标为无,则不计算有效长度
}else{
k++;
}
}
return k;
}
完成size之后,顺势完成较为简单的remove,按照需求,有时会根据内容来消除数组内容,有时又会按照下标来消除内容,考虑到同时输入两个值后,需要通过重写equals才能判断类中的String是否一致,所以采用重载,分别进行int和String两个remove方法。但坏处就是主类中需要多输入一种指令才能执行,不够智能,体验不好。(但实际上这种方法输入的内容更少,只是步骤多了一步。)
void remove(int index){
for(int i = index;i<size()-1;i++){
//检索有效长度,并对后续数据前移
element[i] = element[i+1];
}
//清除最后一位的重复数据
element[size()-1] = null;
System.out.println("数据删除成功,后续数据已按顺序前移补齐空位。");
System.out.println(Arrays.toString(element));
}
void remove(String x){
//设置数据删除时的下标记录器
int k = 0;
for(int i = 0;i<size();i++){
//检索数组,如果数据相同则删除数据,并执行相关后续处理
if (element[i].equals(x)){
for (int j = i;j<size()-1;j++){
//检索数组,执行数据前移,同时也替换要删除的数据
element[i] = element[i+1];
}
//清除最后一位的重复数据
element[size()-1] = null;
}
}
System.out.println("数据删除成功,后续数据已按顺序前移补齐空位。");
System.out.println(Arrays.toString(element));
}
接着处理动态扩容下的自动把输入变量加入尾部的方法。
需要注意的是主类定义时要定好数组的初始情况,这样便于后续逻辑判断,不易报错,以下是主类和add方法的内容:
public class demo3 {
public static void main(String[] args) {
MyList a1 = new MyList();
Scanner input = new Scanner(System.in);
a1.element = new Object[0];
while (true) {
System.out.println("请输入你要进行的操作的序号:1-增加新数据;2-删除数据;3-查询数组内某下标的数据;4-得到数组的有效长度");
int y = input.nextInt();
if (y == 1) {
System.out.println("请输入你要录入的新内容:");
String x = input.next();
a1.add(x);
} else if (y == 2) {
System.out.println("1-删除的是指定下标数据,2-删除指定内容");
int o = input.nextInt();
if (o==1){
System.out.println("请输入你要删除的数组下标:");
int x = input.nextInt();
a1.remove(x);
}else if(o==2){
System.out.println("请输入你要删除的数组下标:");
String x = input.next();
a1.remove(x);
}
} else if (y == 3) {
System.out.println("请输入你要查询的数组下标:");
int x = input.nextInt();
a1.get(x);
} else if (y == 4) {
System.out.println("有效数组长度为:"+a1.size());
}
}
}
}
class MyList{
Object[] element;
void add(String x){
if (size() < element.length) {
element[size()] = x;
} else if (size() == element.length) {
//复制原数组内容到新的大数组中
Object[] elementNew = new Object[element.length + 1];
for (int i = 0; i < element.length; i++) {
//给新数组输入原数据
elementNew[i] = element[i];
}
//给新数组输入新的数据
elementNew[element.length] = x;
//将原数据的名字代替新的数组名字1
this.element = elementNew;
} else {
System.out.println("发生了未知错误!");
}
System.out.println(Arrays.toString(element));
}
}
接着把剩下的读取数组内容的方法添加到MyList类中去:
void get(int index){
if (index>=0 && index<element.length){
System.out.println(element[index]);
}else{
System.out.println("你输入的下标数据错误。");
}
}