扩大
缩小
  

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;
                    }
                }
            }

        }

 


posted @ 2022-06-29 17:44  风筝遇上风  阅读(538)  评论(0编辑  收藏  举报