C#基础之四List的底层实现
使用泛型和索引器来自己实现一个集合类MyList,我们主要实现功能如下:
1.Capacity获取容量大小
2.Add()方法添加元素
3.Insert()方法插入元素
4.[index]访问元素(索引器)
5.Count属性访问元素个数
6.RemoveAt()方法移除指定位置的元素
7.IndexOf()方法取得一个元素所在列表中的索引位置
LastIndexOf()上面的方法是从前往后搜索,这个是从后往前搜索,搜索到满足条件的就停止
上面的两个方法,如果没有找到指定元素就返回-1
8.Sort()对列表中是元素进行从小到大排序
通过自己实现一遍集合,也可以帮助从源码理解List。
定义MyList
//存贮值 private T[] array; //集合中值的个数 private int count = 0;
泛型接口
class MyList<T> where T: IComparable
MyList的构造器
public MyList(int size) { if(size >= 0 && array == null) array = new T[size]; } public MyList() { array = new T[0]; }
MyList的Capacity
public int Capacity { get { return array.Length; } }
索引器
public T GetItem(int index) { if(index >= 0 && index <= Count - 1) { return array[index]; } else { throw new Exception("MyList索引超出异常"); } } public T this[int i] { get { return GetItem(i); } set { if (i >= 0 && i <= Count - 1) { array[i] = value; } //当索引值超出范围 else { throw new Exception("MyList索引超出异常"); } } }
Add操作
当元素增加时,相应的加入到数组中,但当数组满时,需要重新分配数组大小,且重新分配的大小为原先的两倍。
冗余的内存交给GC来释放了。
public void Add(T item) { if(Capacity == Count) { if(Capacity == 0) { array = new T[4]; } else { T[] tempArray = new T[Capacity * 2]; Array.Copy(array, tempArray, Count); array = tempArray; } } array[Count] = item; count++; }
Insert操作
与insert操作类似,主要区别在insert需要在特定位置加入一个值,所以当加入值时,该值后面的值需要向后移动一位。
public void Insert(int index, T item) { if(index >= 0 && index <= Count - 1) { if(Count == Capacity) { var tempArray = new T[Capacity * 2]; Array.Copy(array, tempArray, Count); array = tempArray; } T tmp = array[index]; for (int i = Count - 1; i >= index; i-- ) { array[i+1] = array[i]; } array[index] = item; count++; } else { throw new Exception("MyList索引超出异常"); } }
RemoveAt操作
与insert操作相对应,当删除指定位置的值后,后面的元素分别向前移动一位
public void RemoveAt(int index) { if (index >= 0 && index <= Count - 1) { for(int i = index +1; i < Count; i++) { array[i - 1] = array[i]; } count--; } else { throw new Exception("MyList索引超出异常"); } }
IndexOf和LastIndexOf操作
IndexOf从前往后查找符合值的位置。而LastIndexOf则是从后往前查找符合值的位置
public int IndexOf(T item) { for (int i = 0; i < count; i++ ) { if(array[i].Equals(item)) { return i; } } return -1; } public int LastIndexOf(T item) { for (int i = count - 1; i >= 0; i--) { if (array[i].Equals(item)) { return i; } } return -1; }
Sort操作
该处的排序是简单的冒泡排序,但有一点要注意的是,排序需要进行比较,而该类为泛型,所以需要对泛型进行约束,如下所示在类的定义时约束泛型为IComparable类型,这样才能使用CompareTo方法进行值的比较。
public void Sort() { for (int j = 0; j < count - 1; j++ ) { for (int i = 0; i < count- 1 - j; i++) { if (array[i].CompareTo(array[i + 1]) > 0) { T temp = array[i]; array[i] = array[i + 1]; array[i + 1] = temp; } } } }