关于排序的问题

一、int 和string 类型的的集合的排序

 1 static void Main(string[] args)
 2         {
 3             //ArrayList list = new ArrayList() {1,8,3,992,888,33,77,38,2,34 };//数字
 4             //ArrayList list = new ArrayList() {"Joney","Tindy","Bruce","Wesley","Candy","Alice","Tom"};//字符
 5             ArrayList list = new ArrayList() {"张三","李四","王五","赵六","刘七","钱八"};//数字
 6             Console.WriteLine("排序前:");
 7             for (int i = 0; i < list.Count; i++)
 8             {
 9                 Console.Write(list[i]+" ");
10             }
11             Console.WriteLine("");
12 
13             //排序
14             list.Sort();
15             list.Reverse();
16             //排序后
17             Console.WriteLine("排序后:");
18             for (int i = 0; i < list.Count; i++)
19             {
20                 Console.Write(list[i]+" ");
21             }
22 
23             Console.ReadKey();
24         }
View Code

int 类型,是根据数字大小,降序排列。string类型是根据首字符的汉语拼音排序,这个都比较好理解。如果改成类的实例呢?

 1  static void Main(string[] args)
 2         {
 3             //ArrayList list = new ArrayList() {1,8,3,992,888,33,77,38,2,34 };//数字
 4             //ArrayList list = new ArrayList() {"Joney","Tindy","Bruce","Wesley","Candy","Alice","Tom"};//字符
 5             //ArrayList list = new ArrayList() {"张三","李四","王五","赵六","刘七","钱八"};//数字
 6             ArrayList list = new ArrayList() {
 7                 new Person() { Name="张三" },
 8                 new Person() { Name="李四" },
 9                 new Person() { Name="王五" },
10                 new Person() { Name="赵六" },
11                 new Person() { Name="刘七" },
12                 new Person() {Name="钱八" }
13             };
14             Console.WriteLine("排序前:");
15             for (int i = 0; i < list.Count; i++)
16             {
17                 Console.Write(list[i]+" ");
18             }
19             Console.WriteLine("");
20 
21             //排序
22             list.Sort();
23             list.Reverse();
24             //排序后
25             Console.WriteLine("排序后:");
26             for (int i = 0; i < list.Count; i++)
27             {
28                 Console.Write(list[i]+" ");
29             }
30 
31             Console.ReadKey();
32         }
View Code

上述代码在list.sort()那报错了(无法比较的对象,至少有一个对象实现IComparable)。

这里可以这样理解:前面排序的时候,根据数值大小,字母顺序 排序,但是到了给对象排序的时候,编译器很迷茫,不知道根据什么排序,所以程序报错了,卡在了这里。打开详细信息,提示需要实现IComparable接口。我们把上面的代码改写下:

 1  class Program
 2     {
 3         static void Main(string[] args)
 4         {
 5             //ArrayList list = new ArrayList() {1,8,3,992,888,33,77,38,2,34 };//数字
 6             //ArrayList list = new ArrayList() {"Joney","Tindy","Bruce","Wesley","Candy","Alice","Tom"};//字符
 7             //ArrayList list = new ArrayList() {"张三","李四","王五","赵六","刘七","钱八"};//数字
 8             ArrayList list = new ArrayList() {
 9                 new Person() { Name="张三",Age=18 },
10                 new Person() { Name="李四" ,Age=48},
11                 new Person() { Name="王五",Age=14 },
12                 new Person() { Name="赵六" ,Age=33},
13                 new Person() { Name="刘七",Age=27 },
14                 new Person() {Name="钱八" ,Age=41}
15             };
16             Console.WriteLine("排序前:");
17             for (int i = 0; i < list.Count; i++)
18             {
19                 Console.Write(((Person)list[i]).Name+" ");
20             }
21             Console.WriteLine("");
22 
23             //排序
24             list.Sort();
25             list.Reverse();
26             //排序后
27             Console.WriteLine("排序后:");
28             for (int i = 0; i < list.Count; i++)
29             {
30                 Console.Write(((Person)list[i]).Name + " ");
31             }
32 
33             Console.ReadKey();
34         }
35     }
36 
37     public class Person:IComparable
38     {
39         public string Name { get; set; }
40         public int Age { get; set; }
41         public int CompareTo(object obj)
42         {
43             Person p=obj as Person;
44             if (p != null)
45             {
46                 return p.Age - this.Age;
47             }
48             else
49             {
50                 throw new InvalidOperationException("无效的操作");
51             }
52         }
53     }
View Code

输出后的结果是根据年龄升序排列的:

排序前:
张三 李四 王五 赵六 刘七 钱八
排序后:
王五 张三 刘七 赵六 钱八 李四

其实我们看反编译后的代码,不管是int还是string,都实现了IComparable接口。也就是说,想调用ArrayList中sort()方法排序,集合中的元素都必须实现IComparable接口。

接下来,我们把程序写得灵活点。上面我们把排序的字段写死了,如果更换排序的依据,需要更改方法中的代码。我们能否不改类中方法中的代码,也能根据用户的想法排序呢?这需要我们写个排序的比较器。

 1 class Program
 2     {
 3         static void Main(string[] args)
 4         {
 5             //ArrayList list = new ArrayList() {1,8,3,992,888,33,77,38,2,34 };//数字
 6             //ArrayList list = new ArrayList() {"Joney","Tindy","Bruce","Wesley","Candy","Alice","Tom"};//字符
 7             //ArrayList list = new ArrayList() {"张三","李四","王五","赵六","刘七","钱八"};//数字
 8             ArrayList list = new ArrayList() {
 9                 new Person() { Name="张三",Age=18 },
10                 new Person() { Name="李四" ,Age=48},
11                 new Person() { Name="王五",Age=14 },
12                 new Person() { Name="赵六" ,Age=33},
13                 new Person() { Name="刘七",Age=27 },
14                 new Person() {Name="钱八" ,Age=41}
15             };
16             Console.WriteLine("排序前:");
17             for (int i = 0; i < list.Count; i++)
18             {
19                 Console.Write(((Person)list[i]).Name+" ");
20             }
21             Console.WriteLine("");
22 
23             //排序
24             list.Sort(new SortPersonByName());
25             //list.Reverse();
26             //排序后
27             Console.WriteLine("排序后:");
28             for (int i = 0; i < list.Count; i++)
29             {
30                 Console.Write(((Person)list[i]).Name + " ");
31             }
32 
33             Console.ReadKey();
34         }
35     }
36 
37     /// <summary>
38     /// 根据姓氏排序
39     /// </summary>
40     public class SortPersonByName : IComparer
41     {
42         public int Compare(object x, object y)
43         {
44             Person p1 = x as Person;
45             Person p2 = y as Person;
46             if (p1 != null && p2 != null)
47             {
48                 return p1.Name.CompareTo(p2.Name);
49             }
50             else
51             {
52                 throw new Exception("排序异常");
53             }
54         }
55     }
56 
57     /// <summary>
58     /// 根据年龄排序
59     /// </summary>
60     public class SortPersonByAge : IComparer
61     {
62         public int Compare(object x, object y)
63         {
64             Person p1 = x as Person;
65             Person p2 = y as Person;
66             if (p1!=null&&p2!=null)
67             {
68                 return p1.Age - p2.Age;
69             }
70             else
71             {
72                 throw new Exception("排序异常");
73             }
74         }
75     }
View Code

如上代码,我们在调用list.sort()的时候传入自己编写的比较器,就可以个性化定制排序依据。需要强调的是,根据对象的Name排序的时候,由于字符串本身有compareto方法,可以直接调用。

原文地址:https://www.cnblogs.com/wesley168/p/6519611.html