使用泛型来创建我们自己的列表

在前面我们知道在C#中有一个List类,可以存储长度不限的数据。列表是使用了泛型来创建的,那我们可以通过泛型来创建自己的一个列表,这样我们能够对泛型和列表有个更深刻的了解。


首先,我们知道列表其实就是一个数组,只不过构造的时候不需要指定长度,那么我们首先要定义一个泛型数组和其中元素个数的变量。

class MyList<T> where T:IComparable
    {
        private T[] array; //定义一个泛型数组
        private int count; //元素个数
    }

有了MyList这个类之后,我们要去定义他的构造函数,数组长度可填可不填。

        //构造有参数组
        public MyList(int size)
        {
            if (size >= 0)
            {
                array = new T[size];
            }
        }

        //构造无参数组
        public MyList()
        {
            array = new T[0];
        }

这样我们的列表就可以通过构造函数构造出来了,那么列表的基本属性是什么呢?我们要能够获取这个列表的容量大小和元素个数。因为容量大小和元素个数我们只需要获取它的数值,所以不用设置set方法。

//获取容量大小
        public int Capacity
        {
            get { return array.Length; }
        }

        //获取数组内元素个数
        public int Count
        {
            get { return count; }
        }

现在这个列表的构造函数和属性都已经写好了,那么接下来我们需要写这个列表的功能。功能如下

1.Add()方法添加元素

//添加元素
        public void Add(T item)
        {
            //首先判断数组元素是否已满
            if (Capacity == Count)
            {
                //再判断数组是否为空
                if (Capacity == 0)
                {
                    array = new T[4];
                }
                else
                {
                    //不为空的话数组长度增加为原来的两倍
                    var newArray = new T[Capacity * 2];
                    Array.Copy(array, newArray, count);
                    array = newArray;
                }
            }
            array[Count] = item;
            count++;
        }

2.获取列表的值(为了更方便地访问列表,我们可以使用索引器访问元素)

//获取列表的值
        public T GetItem(int index)
        {
            if (index >= 0 && index <= count - 1)
            {
                return array[index];
            }
            else
            {
                throw new Exception("索引超出范围");
            }
        }

//通过索引访问元素
        public T this[int index] //从源码所获取的方法
        {
            get { return GetItem(index); }
            set
            {
                if (index >= 0 && index <= count - 1)
                {
                    array[index] = value;
                }
                else
                {
                    throw new Exception("索引超出范围");
                }
            }
        }

3.插入元素

public void Insert(int index, T item)
        {
            if (index >= 0 && index <= count - 1)
            {
                //首先判断数组是否已满
                if (Capacity == Count)
                {
                    //再判断数组是否为空
                    if (Capacity == 0)
                    {
                        array = new T[4];
                    }
                    else
                    {
                        //不为空的话数组长度增加为原来的两倍
                        var newArray = new T[Capacity * 2];
                        Array.Copy(array, newArray, count);
                        array = newArray;
                    }
                }
                else
                {
                    for (int i = count - 1; i >= index; i--)
                    {
                        array[i + 1] = array[i];
                    }
                    array[index] = item;
                    count++; //插入完之后元素个数自增
                }
            }
            else
            {
                throw new Exception("索引超出范围");
            }
        }

4.移除指定位置元素

public void RemoveAt(int index)
        {
            if (index >= 0 && index <= count - 1)
            {
                for(int i = index + 1; i <= count - 1; i++)
                {
                    array[i - 1] = array[i]; //将后一个元素的值赋值给前一个元素;
                }
                count--;
            }
            else
            {
                throw new Exception("索引超出范围");
            }
        }

5.从前往后取得元素在列表中的索引

//从前往后取得元素在列表中的索引
        public int IndexOf(T item)
        {
            for(int i = 0; i <= count - 1; i++)
            {
                //if(array[i] == item) 因为泛型不能做比较,所以使用equals方法
                if(array[i].Equals(item))
                {
                    return i;
                }
            }
            return -1;
        }

6.从后往前取得元素在列表中的索引

//从后往前取得元素在列表中的索引
        public int LastIndexOf(T item)
        {
            for(int i = count - 1; i >= 0; i--)
            {
                if (array[i].Equals(item))
                {
                    return i;
                }
            }
            return -1;
        }

7.对列表中的元素进行排序(冒泡排序)

public void Sort()
        {
            for(int i = 0; i < count - 1; i++)
            {
                for(int j = 0; j < count - 1 - i; j++) //减去一个i是不遍历已经排序过的元素,提高效率
                {
                    //if (array[i] < array[i + 1]) 因为泛型无法比较大小,所以让泛型使用Compare接口
                    if (array[j].CompareTo(array[j + 1]) > 0)
                    {
                        var temp = array[j];
                        array[j] = array[j + 1];
                        array[j + 1] = temp;
                    }
                }
            }
        }

在这些功能里,有些地方值得注意一下

  1. 使用泛型声明的元素,当判断是否相等的时候,不能使用”==”来判断,只能使用Equals()方法来判断是否相等。
  2. 使用泛型声明的元素,当判断两者的大小时,不能使用”>”或”<”来判断,我们需要在类名后面加上”where T:ICompareble”,给泛型继承ICompareble接口,然后使用CompareTo()方法,当比较完的值>0时,说明前面那个数比后面的数大,<0时说明前面的数比后面的数小。

下面贴出源代码

class MyList<T> where T:IComparable
    {
        private T[] array; //定义一个泛型数组
        private int count; //元素个数

        //构造有参数组
        public MyList(int size)
        {
            if (size >= 0)
            {
                array = new T[size];
            }
        }

        //构造无参数组
        public MyList()
        {
            array = new T[0];
        }

        //获取容量大小
        public int Capacity
        {
            get { return array.Length; }
        }

        //获取数组内元素个数
        public int Count
        {
            get { return count; }
        }

        //添加元素
        public void Add(T item)
        {
            //首先判断数组元素是否已满
            if (Capacity == Count)
            {
                //再判断数组是否为空
                if (Capacity == 0)
                {
                    array = new T[4];
                }
                else
                {
                    //不为空的话数组长度增加为原来的两倍
                    var newArray = new T[Capacity * 2];
                    Array.Copy(array, newArray, count);
                    array = newArray;
                }
            }
            array[Count] = item;
            count++;
        }

        //获取列表的值
        public T GetItem(int index)
        {
            if (index >= 0 && index <= count - 1)
            {
                return array[index];
            }
            else
            {
                throw new Exception("索引超出范围");
            }
        }

        //通过索引访问元素
        public T this[int index] //从源码所获取的方法
        {
            get { return GetItem(index); }
            set
            {
                if (index >= 0 && index <= count - 1)
                {
                    array[index] = value;
                }
                else
                {
                    throw new Exception("索引超出范围");
                }
            }
        }

        //插入元素
        public void Insert(int index, T item)
        {
            if (index >= 0 && index <= count - 1)
            {
                //首先判断数组是否已满
                if (Capacity == Count)
                {
                    //再判断数组是否为空
                    if (Capacity == 0)
                    {
                        array = new T[4];
                    }
                    else
                    {
                        //不为空的话数组长度增加为原来的两倍
                        var newArray = new T[Capacity * 2];
                        Array.Copy(array, newArray, count);
                        array = newArray;
                    }
                }
                else
                {
                    for (int i = count - 1; i >= index; i--)
                    {
                        array[i + 1] = array[i];
                    }
                    array[index] = item;
                    count++; //插入完之后元素个数自增
                }
            }
            else
            {
                throw new Exception("索引超出范围");
            }
        }

        //移除指定位置元素
        public void RemoveAt(int index)
        {
            if (index >= 0 && index <= count - 1)
            {
                for(int i = index + 1; i <= count - 1; i++)
                {
                    array[i - 1] = array[i]; //将后一个元素的值赋值给前一个元素;
                }
                count--;
            }
            else
            {
                throw new Exception("索引超出范围");
            }
        }

        //从前往后取得元素在列表中的索引
        public int IndexOf(T item)
        {
            for(int i = 0; i <= count - 1; i++)
            {
                //if(array[i] == item) 因为泛型不能做比较,所以使用equals方法
                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;
        }

        //对列表中的元素进行排序(冒泡排序)
        public void Sort()
        {
            for(int i = 0; i < count - 1; i++)
            {
                for(int j = 0; j < count - 1 - i; j++) //减去一个i是不遍历已经排序过的元素,提高效率
                {
                    //if (array[i] < array[i + 1]) 因为泛型无法比较大小,所以让泛型使用Compare接口
                    if (array[j].CompareTo(array[j + 1]) > 0)
                    {
                        var temp = array[j];
                        array[j] = array[j + 1];
                        array[j + 1] = temp;
                    }
                }
            }
        }
    }

//主函数
class Program
    {
        static void Main(string[] args)
        {
            MyList<int> myList = new MyList<int>();
            myList.Add(128);
            myList.Add(27);
            myList.Add(94);
            myList.Add(18);
            myList.Add(349);
            myList.Add(83);
            myList.Add(837);
            myList.Add(250);
            myList.Add(430);
            myList.Add(678);
            myList.Insert(0, 1000);
            myList.RemoveAt(8);
            for(int i = 0; i < myList.Count; i++)
            {
                Console.Write(myList[i] + " ");
            }
            Console.WriteLine();
            Console.WriteLine(myList.IndexOf(83));
            Console.WriteLine(myList.LastIndexOf(18));
            Console.WriteLine();
            myList.Sort();
            for (int i = 0; i < myList.Count; i++)
            {
                Console.Write(myList[i] + " ");
            }
            Console.ReadKey();
        }
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值