.NET Framework System.Array.Sort 演示_.NET_编程开发_程序员俱乐部

中国优秀的程序员网站程序员频道CXYCLUB技术地图
热搜:
更多>>
 
您所在的位置: 程序员俱乐部 > 编程开发 > .NET > .NET Framework System.Array.Sort 演示

.NET Framework System.Array.Sort 演示

 2015/2/6 15:18:18  IGod接口  程序员俱乐部  我要评论(0)
  • 摘要:本文内容自定义类Array.Sort参考资料System.Array.Sort有很多对集合的操作,比如排序,查找,克隆等等,你可以利用这个类加深对IComparer、IComparable、ICloneable以及泛型委托、匿名方法、Lambda表达式的理解。下载Demo自定义类自定义后面用到的Person类和PersonComparer类。自定义Person类,该类有两个属性:lastname和firstname,重构了ToString方法
  • 标签:.net system Framework net

本文内容

System.Array.Sort 有很多对集合的操作,比如排序,查找,克隆等等,你可以利用这个类加深对 IComparer、IComparable、ICloneable 以及泛型委托、匿名方法、Lambda 表达式理解

下载 Demo

自定义类


自定义后面用到的 Person 类和 PersonComparer 类。

自定义 Person 类,该类有两个属性:last name 和 first name,重构了 ToString 方法。Person 类还继承 IComparableICloneable 接口,实现了 CompareTo 和 Clone 方法。CompareTo 方法在后面的集合排序时会用到,它通常是默认的排序。如下所示:

monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">public class Person : IComparable, ICloneable
{
    public Person()
    {
 
    }
 
    public Person(string firstname, string lastname)
    {
        this.FirstName = firstname;
        this.LastName = lastname;
    }
 
    public string FirstName { get; set; }
 
    public string LastName { get; set; }
 
    public override string ToString()
    {
        return string.Format("{0} {1}", FirstName, LastName);
    }
 
    public int CompareTo(object obj)
    {
        Person other = obj as Person;
        return this.LastName.CompareTo(other.LastName);
    }
 
    public object Clone()
    {
        return new Person(FirstName, LastName);
    }
}

自定义 PersonComparer 类,该类内定义了比较类型,可以选择按 last name 比较,还是 first name。PersonComparer 类同时继承 IComparer 接口的非泛型形式和泛型形式,实现了它们相应的 Compare 方法,该方法在后面的集合排序中会用到。如下所示:

public class PersonComparer : IComparer, IComparer<Person>
{
    public enum PersonCompareType
    {
        FirstName,
        LastName
    }
 
    private PersonCompareType compareType;
 
    public PersonComparer(PersonCompareType compareType)
    {
        this.compareType = compareType;
    }
 
    public int Compare(object x, object y)
    {
        Person p1 = x as Person;
        Person p2 = y as Person;
        switch (compareType)
        {
            case PersonCompareType.FirstName:
                return p1.FirstName.CompareTo(p2.FirstName);
            case PersonCompareType.LastName:
                return p1.LastName.CompareTo(p2.LastName);
            default:
                throw new ArgumentException("unexpected compare type");
        }
    }
    public int Compare(Person x, Person y)
    {
        Person p1 = x;
        Person p2 = y;
        switch (compareType)
        {
            case PersonCompareType.FirstName:
                return p1.FirstName.CompareTo(p2.FirstName);
            case PersonCompareType.LastName:
                return p1.LastName.CompareTo(p2.LastName);
            default:
                throw new ArgumentException("unexpected compare type");
        }
    }
}

Array.Sort


Array.Sort 有 17 个“重载”,如下所示:

Sort(Array)      
Sort(Array, Array)      
Sort(Array, IComparer)      
Sort(Array, Array, IComparer)      
Sort(Array, Int32, Int32)      
Sort(Array, Array, Int32, Int32)       
Sort(Array, Int32, Int32, IComparer)      
Sort(Array, Array, Int32, Int32, IComparer)         
Sort<T>(T[])       
Sort<T>(T[], IComparer<T>)      
Sort<T>(T[], Comparison<T>)      
Sort<T>(T[], Int32, Int32)       
Sort<T>(T[], Int32, Int32, IComparer<T>)      
Sort<TKey, TValue>(TKey[], TValue[])        
Sort<TKey, TValue>(TKey[], TValue[], IComparer<TKey>)        
Sort<TKey, TValue>(TKey[], TValue[], Int32, Int32)        
Sort<TKey, TValue>(TKey[], TValue[], Int32, Int32, IComparer<TKey>)

从它们的参数,你可以先想象一下:

  • 这些方法可以分成非泛型形式和泛型形式,也就是每个非泛型形式基本都会对应一个泛型形式;
  • 如果我们要对一个集合排序,肯定是要比较的,并且默认是升序;
  • 如果集合是字符串,那很好办,几乎不需要做什么;
  • 可如果集合是对象,那我们就必须指定两个对象之间如何比较以及比较什么;
  • 如果有两个集合,一个集合是当键,另一个集合是当值,用键为值排序,这当然也是可以的,比如 Sort<TKey, TValue>
  • 针对不同的情况,可以指定不同的比较方法,比如,参数中带 ICompare 的。

如果集合仅仅是字符串数组,那很好办,如下代码所示,按升序排序:

string[] names = { "Emerson Fittipaldi", "Niki Lauda", "Ayrton Senna", "Michael Schumacher" };
Array.Sort(names);

但外国人的姓在后面,要是按我们的规矩如何按姓排序?字符串数组就不行了,此时就需要自定义的 Person 类,假设有如下 Person 数组:

Person[] persons = {
    new Person("Emerson", "Fittipaldi"),
    new Person("Niki", "Lauda"),
    new Person("Ayrton", "Senna"),
    new Person("Michael", "Schumacher")
};

按姓的升序排序,采用 Sort(Array) 这个方法,如下代码所示:

Array.Sort(persons);

因为前面定义的 Person 类是继承了 IComparer 接口,并实现了 CompareTo 方法,里面规定了按姓 last name 比较,所以 Array.Sort 方法就知道如何排序了。

如果有时需要按 first name 排序,有时需要用 last name,该怎么办?这是就需要自定义的类 PersonComparer。采用 Sort(Array, IComparer) 这个方法,代码如下所示:

Array.Sort(persons, new PersonComparer(PersonComparer.PersonCompareType.FirstName));
 
Console.WriteLine("Sort By First Name:");
foreach (Person p in persons)
{
    Console.WriteLine("     " + p);
}
 
Array.Sort(persons, new PersonComparer(PersonComparer.PersonCompareType.LastName));
 
Console.WriteLine("Sort By Last Name:");
foreach (Person p in persons)
{
    Console.WriteLine("     " + p);
}

结果:

Sort By First Name:
     Ayrton Senna
     Emerson Fittipaldi
     Michael Schumacher
     Niki Lauda
Sort By Last Name:
     Emerson Fittipaldi
     Niki Lauda
     Michael Schumacher
     Ayrton Senna

如果我们事先没定义 PersonComparer 类,也没问题,可以采用 Sort<T>(T[], Comparison<T>) 这个方法,参数 Comparison<T> 是泛型委托,这意味着我们可以用匿名方法或 Lambda 表达式来规定 Person 如何比较以及比较什么,代码如下所示:

Array.Sort(persons,
    delegate(Person p1, Person p2)
    {
        return p1.FirstName.CompareTo(p2.FirstName);
    });
 
Array.Sort(persons,
    delegate(Person p1, Person p2)
    {
        return p1.LastName.CompareTo(p2.LastName);
    });

Array.Sort(persons, (p1, p2) => p1.FirstName.CompareTo(p2.FirstName));
 
Array.Sort(persons, (p1, p2) => p1.LastName.CompareTo(p2.LastName));

如果用两个集合呢?一个集合用当键,另一个集合当值,用键为值排序,如下代码所示:

Person[] personKeys = {
    new Person("Emerson", "Fittipaldi"),
    new Person("Niki", "Lauda"),
    new Person("Ayrton", "Senna"),
    new Person("Michael", "Schumacher")
};
Person[] personValues = {
    new Person("Emerson", "Fittipaldi"),
    new Person("Niki", "Lauda"),
    new Person("Ayrton", "Senna"),
    new Person("Michael", "Schumacher")
};
 
Array.Sort<Person, Person>(personKeys, personValues);
Array.Sort<Person, Person>(personKeys, personValues, new PersonComparer(PersonComparer.PersonCompareType.FirstName));

Sort 两个参数的泛型方法,personValues 会按 personKeys 的 LastName 排序;而 Sort 三个参数的泛型方法,指定了 personKeys 按 FirstName 排序。

 

知道 Array.Sort 的用法,其他方法,像检索方法,BinarySearch、Find*** 开头,以及 indexOf 相关,就很好理解了。

 

参考资料


 

下载 Demo

发表评论
用户名: 匿名