作业讲解"/>
索引器小作业讲解
作业:自定义一个整形数组类,该类中有一个整形数组变量为它封装增删查改的方法。
class IntArray {//整形数组类private int[]array;
//整形数组变量
}
增删查改,说明至少要有四个方法。这篇文章主要讲增删这两个方法。
而查与改,可以用到索引器的get和set方法。先简单的写一下。
class IntArray
{private int[] array;public int this[int index]
{get{return array[index];}set{array[index] = value;}}}
增删,索引器肯定是没法做到的,所以我们自己写方法。
public void Add(int value){
}
public void Remove(int value){
}
public void RemoveAt(int index){
}//这里提供了两个删除的方法,一个是直接删除,一个是通过位置删除。
那基本框架就有了。数组还没有实例化,我们肯定是希望把IntArray实例化对象的时候就一起实例化,所以我们写一个构造函数(为了初始化数组变量)。
public IntArray(){}
问题来了,数组长度默认是多少?
我们都知道,数组的长度一旦初始化就没有办法动态改了。如果要增加,只能去扩容,通过“搬家”的形式。(这个看不懂的可以留个言,我后期会写一篇介绍“数组搬家”)。
这种搬家的形式是非常占用内存的,每次都要产生垃圾。主要是因为在进行扩容时需要创建一个新的更大的数组,并将原数组中的元素全部复制到新数组中。
当创建一个新的更大的数组时,系统需要分配一块足够大的内存空间来存储新数组,而原数组所占据的内存空间也需要保留一段时间,直到原数组中的元素被完全复制到新数组中。这就意味着在扩容期间,系统中同时存在两块大小相差较大的内存空间,这会导致内存的浪费。
当将原数组中的元素复制到新数组中时,会产生临时的重复数据,即在原数组和新数组中同时存在相同的元素。在复制完成之后,原数组中的元素会被释放,但在复制过程中产生的临时重复数据就会成为垃圾内存,因为它们不再被使用,却占据着内存空间。
因此,数组扩容使用"搬家"的形式很容易导致内存的浪费和产生垃圾内存,对于大规模数据操作频繁的场景,应该考虑使用其他数据结构来避免频繁的数组扩容操作。
我们可以一开始就给容器一定的长度,一开始就给它开五个房间。
假设数组里面还没有元素,这五个房间里什么都没有,它的长度L(length)就是0,容量C(capacity)就是5。
我们逐渐一个一个往房间里放元素,放一个,L就加1。一直加到L=C,就意味着放满了。然后就该扩容了。这个时候,至少我们放五次才会产生垃圾,而不是放一次就产生一次垃圾。
然后比如我们要扩成10,就把C设置为10,再按照上面的方法,一个一个往房间里放元素,放一个,L就加1。一直加到L=C,就意味着放满了。又该扩容了。
那我们带着这样一个思路,来写:
//声明两个变量
//房间容量private int capacity;//当前放了几个房间,也就是哪几个房间已经放了内容。private int length;
初始化:
public IntArray()
{capacity = 5;length = 0;array = new int[capacity];}
接着开始写增的方法:
public void Add(int value)
{if (length < capacity)//L只要不小于C就意味着该扩容了{array[length] = value;++length;}else //进行扩容,涉及搬家{capacity *= 2;//扩2倍//声明新的房间,新的容量int[]tempArray = new int[capacity];//老东西放进新房子里for (int i = 0; i < array.Length; i++){tempArray[i] = array[i];}//老房子的地址 指向新房子的地址array = tempArray;//接着往后面放,把新值放到第五个以及以后的房间里array[length] = value;++length;}}
测试一下:
static void Main(string[] args){IntArray array1= new IntArray();array1.Add(100);Console.WriteLine(array1[0]);//用索引器}
封装有什么好处?以前数组在外面声明的话,就要在外面写扩容的逻辑。现在我们把扩容封装在Add方法里面了,那我们就不用关心数组长度,容量到底多少,可以new了往里面加。扩容在方法里面,让它去处理。
static void Main(string[] args){Person p = new Person();p[0] = new Person();IntArray array1= new IntArray();array1.Add(100);array1.Add(200);array1.Add(300);array1.Add(400);array1.Add(500);array1.Add(600);array1.Add(700);array1.Add(800);Console.WriteLine(array1[0]);}
打印结果:100
🆗,带着这样的思路,写删除方法也简单了。
public void RemoveAt(int index)//上传要删的索引值{if(index > length - 1){Console.WriteLine("你越界了");return;}for (int i = index; i < length-1; i++){array[i] = array[i + 1];}--length;}
看不懂的童鞋,我举个例子,如果要删索引为2的元素,那就从2开始遍历,让索引为2的值等于索引为3的值,索引为2的值就被覆盖,就不存在了。
换句话说,在这个过程中,原先的array[i+1]的值被移动到了位置i,而原先的array[i+2]的值被移动到了位置i+1,依次类推,直到倒数第二个元素的值都被向前移动了一位。
static void Main(string[] args)
{Person p = new Person();p[0] = new Person();IntArray array1= new IntArray();array1.Add(100);array1.Add(200);array1.Add(300);array1.Add(400);array1.Add(500);array1.Add(600);array1.Add(700);array1.RemoveAt(1);Console.WriteLine(array1[1]);}
打印结果:300
那么直接删除的方法也很好写了:
public void Remove(int value){for (int i = 0; i < length; i++){if (array[i] == value){RemoveAt(i);return;}}Console.WriteLine("没有找到");}
接着补上索引器(查与改),整个代码作业就完成了:
internal class Program{class IntArray {private int[] array;//房间容量private int capacity;//当前放了几个房间private int length;public IntArray(){capacity = 5;length = 0;array = new int[capacity];}//如果增加就涉及扩容.容量和长度相等的时候就扩容//扩容就涉及搬家public void Add(int value){if (length < capacity){array[length] = value;++length;}else{capacity *= 2;int[]tempArray = new int[capacity];//老东西放进新房子里for (int i = 0; i < array.Length; i++){tempArray[i] = array[i];}//老房子的地址 指向新房子的地址array = tempArray;//接着往后面放array[length] = value;++length;}}public void Remove(int value){for (int i = 0; i < length; i++){if (array[i] == value){RemoveAt(i);return;}}Console.WriteLine("没有找到");}public void RemoveAt(int index){if(index > length - 1){Console.WriteLine("你越界了");return;}for (int i = index; i < length-1; i++){array[i] = array[i + 1];}--length;}public int this[int index]{get{if(index >= length|| index <0){Console.WriteLine("越界");}return array[index];}set{if (index >= length || index < 0){Console.WriteLine("越界");}array[index] = value;}}}static void Main(string[] args){IntArray array1= new IntArray();array1.Add(100);array1.Add(200);array1.Add(300);array1.Add(400);array1.Add(500);array1.Add(600);array1.Add(700);array1.RemoveAt(1);Console.WriteLine(array1[1]);}}
同学们可以自行测试一下~有什么问题评论区欢迎留言~
更多推荐
索引器小作业讲解
发布评论