目录
1.系统排序原理
当我们对一个List<int>类型的数组如list1排序时,一个轻松的list1.sort();帮我们解决了问题
但是在实际应用过程中,往往我们遇到的问题会更加棘手
比如这样一个类:
class BagItem
{
public int id;
public string name;
public int count;
public BagItem(int id, string name, int count)
{
this.id = id;
this.name = name;
this.count = count;
}
}
这是一个背包物品类,包含了物品编号id,物品名称name,物品数量count
List<BagItem> bagItems = new List<BagItem>();
//传入参数依次为id,name,count
bagItems.Add(new BagItem(1, "生命药水", 5));
bagItems.Add(new BagItem(2, "魔力药水", 12));
bagItems.Add(new BagItem(3, "速度药水", 7));
bagItems.Add(new BagItem(4, "铁皮药水", 3));
bagItems.Add(new BagItem(5, "重力药水", 9));
bagItems.Add(new BagItem(6, "回城药水", 2));
bagItems.Sort();
当我们创建一个List<BagItem>数组并想对它排序时,猜猜会发生什么?
这时系统会报错
想要弄明白为什么报错,需要先解释一个sort排序的原理
sort排序时会用到CompareTo函数,这个函数方法存放在IComparable接口中
之前我们List<int>类型数组排序能够成功是因为int类调用了上述接口并实现,所以sort排序时可以成功运行
![](https://img-blog.csdnimg.cn/direct/cf8c35a77a2e46afa1f15de9938de839.png)
而我们自己写的类调用不到对应类型的函数,所以运行失败
接下来将介绍两种方法时得我们自己写的类可以成功排序
2.方式一:调用接口并重写
既然int类可以调用,我们也可以给自己写的类调用这个接口
class BagItem:IComparable<BagItem>
{
public int id;
public string name;
public int count;
public BagItem(int id, string name, int count)
{
this.id = id;
this.name = name;
this.count = count;
}
public int CompareTo(BagItem other)
{
//返回类型int
//返回值>0时,当前成员排在other成员右边
//返回值<0时,当前成员排在other成员左边
//可以理解为other成员处于0位置
if (other.count > this.count || (other.count == this.count && other.id >= this.id))
return -1;
else
return 1;
}
}
internal class Program
{
static void Main(string[] args)
{
List<BagItem> bagItems = new List<BagItem>();
//传入参数依次为id,name,count
bagItems.Add(new BagItem(3, "生命药水", 5));
bagItems.Add(new BagItem(2, "魔力药水", 12));
bagItems.Add(new BagItem(1, "速度药水", 12));
bagItems.Add(new BagItem(5, "铁皮药水", 3));
bagItems.Add(new BagItem(4, "重力药水", 9));
bagItems.Add(new BagItem(6, "回城药水", 2));
foreach (BagItem item in bagItems)
{
Console.WriteLine("物品:{0},id:{1},数量{2}",item.name,item.id,item.count);
}
bagItems.Sort();
Console.WriteLine("---------------------");
foreach (BagItem item in bagItems)
{
Console.WriteLine("物品:{0},id:{1},数量{2}", item.name, item.id, item.count);
}
}
}
3.方式二:传排序规则函数做参数
当我们查看sort用法时,我们可以看到它还有其他重载类型
我们默认使用的是第三种无参数的类型,如果我们写一个函数作为参数传入时,那么就可以使用第一类型,传入我们自己的比较规则。
internal class Program
{
static void Main(string[] args)
{
List<BagItem> bagItems = new List<BagItem>();
//传入参数依次为id,name,count
bagItems.Add(new BagItem(3, "生命药水", 5));
bagItems.Add(new BagItem(2, "魔力药水", 12));
bagItems.Add(new BagItem(1, "速度药水", 12));
bagItems.Add(new BagItem(5, "铁皮药水", 3));
bagItems.Add(new BagItem(4, "重力药水", 9));
bagItems.Add(new BagItem(6, "回城药水", 2));
foreach (BagItem item in bagItems)
{
Console.WriteLine("物品:{0},id:{1},数量{2}",item.name,item.id,item.count);
}
bagItems.Sort(SortBagItems);
Console.WriteLine("---------------------");
foreach (BagItem item in bagItems)
{
Console.WriteLine("物品:{0},id:{1},数量{2}", item.name, item.id, item.count);
}
}
static int SortBagItems(BagItem left,BagItem right)
{
//返回类型int
//返回值>0时,当前成员排在other成员右边
//返回值<0时,当前成员排在other成员左边
//可以理解为other成员处于0位置
if (right.count > left.count || (right.count == left.count && right.id >= left.id))
return -1;
else
return 1;
}
}