本文内容

  • 自定义类
  • Array.Sort
  • 参考资料

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

下载 Demo

自定义类


自定义两个类:PersonPersonComparer 。后面会用到这两个类。

自定义 Person

Person 类有两个属性:FirstNameLastName,重构了 ToString 方法。该类还继承 IComparable 接口,实现了 CompareTo 方法,会在后面 Array.Sort 方法中用到。如下所示:

public class Person : IComparable

{

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

    }

}

说明:CompareTo 方法,它提供了默认比较,按 LastName 升序排序。

自定义 PersonComparer  类

该类内部定义了一个比较类型,可以按 FirstNameLastName 比较,并且都是升序排序。PersonComparer 类同时继承 IComparer 接口的非泛型形式和泛型形式,实现了它们相应的 Compare 方法,该方法会在 Array.Sort 中用到。如下所示:

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 的。可以指定按 LastName 升序或降序,或 FirstName 升序或降序 。

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

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 方法,里面规定了按姓 LastName 比较,并且是升序,所以 Array.Sort 方法就知道如何排序了。

如果有时需要按 FirstName 排序,有时用 LastName,怎么办?这就需要自定义的类 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> 是 .Net 提供的泛型委托,这意味着我们可以用匿名方法或 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);

    });

或采用 Lambda 表达式形式:

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

 

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

如果有两个集合,让其中一个集合为另一个集合排序呢?若有两个 Person 集合,一模一样,只是一个当键,另一个当值,用键为值排序,如下代码所示:

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 会按 personKeysLastName 按升序排序。这是默认的;

  • Sort 有三个参数的泛型方法,personValues 会按 personKeysFirstName 按升序排序。

Array 中的其他方法,像 BinarySearch、Find 相关和 indexOf 相关,跟 Sort 用法类似,因为它们的参数大都是 IComparer、IComparable 以及泛型委托。

参考资料


下载 Demo

.NET Framework System.Array.Sort 数组类,加深对 IComparer、IComparable 以及泛型委托、匿名方法、Lambda 表达式的理解的更多相关文章

  1. C#高级编程笔记 (1至6章节)数组,类/方法/泛型

    2.3变量 var 类型推断 type 类的分类 如:type nametype = name.GetType(); //取变量name的类型 const 常量  const int painame ...

  2. 【system.array】使用说明

    对象:system.array 说明:提供一系列针对数组类型的操作 目录: 方法 返回 说明 system.array.join( array, separator ) [String]  将数组转换 ...

  3. 【java集合总结】-- 数组总结+自己封装数组类

    一.前言 本篇文章总结目前学习的有关数组方面的知识,首先总结一下数组相关的核心概念,然后在封装一个自己的泛型动态数组类(ava已经封装的有现成的,自己封装只是为了加深理解),最后再学习解析下Array ...

  4. .NET 排序 Array.Sort<T> 实现分析

    System.Array.Sort<T> 是.NET内置的排序方法, 灵活且高效, 大家都学过一些排序算法,比如冒泡排序,插入排序,堆排序等,不过你知道这个方法背后使用了什么排序算法吗? ...

  5. Java8 Collections.sort()及Arrays.sort()中Lambda表达式及增强版Comparator的使用

    摘要:本文主要介绍Java8 中Arrays.sort()及Collections.sort()中Lambda表达式及增强版Comparator的使用. 不废话直接上代码 import com.goo ...

  6. java语言中的匿名类与lambda表达式介绍与总结 (Anonymous Classes and Lambda Expressions)

    2017/6/30 转载写明出处:http://www.cnblogs.com/daren-lin/p/anonymous-classes-and-lambda-expressions-in-java ...

  7. Effective Java 第三版——42.lambda表达式优于匿名类

    Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将 ...

  8. [ActionScript 3.0] 对数组中的元素进行排序Array.sort()的方法

    对数组中的元素进行排序. 此方法按 Unicode 值排序. (ASCII 是 Unicode 的一个子集.) 默认情况下,Array.sort()按以下方式进行排序: 1. 排序区分大小写(Z优先于 ...

  9. Array(数组)对象-->sort() 方法

    1.定义和用法 sort() 方法用于对数组的元素进行排序. 默认排序顺序为按字母升序. 语法: array.sort(sortfunction) 参数: sortfunction:规定排序顺序.必须 ...

随机推荐

  1. Android Studio 怎样打JAR包

    Android Studio 怎样打JAR包 在eclipse中我们知道怎样将一个项目导出为jar包,供其他项目使用. 在AS中能够通过改动gradle才处理. 我们新建一个项目MakeJar,在项目 ...

  2. android:活动的最佳实践

    2.6.1    知晓当前是在哪一个活动 这个技巧将教会你,如何根据程序当前的界面就能判断出这是哪一个活动.可能你会觉 得挺纳闷的,我自己写的代码怎么会不知道这是哪一个活动呢?很不幸的是,在你真正进入 ...

  3. canvas使用2

    文字对齐方式 : 水平对齐 ? 1 2 3 4 //是用 textAlign 属性设置水平对齐方式(默认坐标点) ctx.textAlign = "start"; ctx.font ...

  4. mormot支持https

    mormot支持https 将ssl证书导入电脑系统,以Windows 10为例: 运行 mmc 证书导入成功后,双击证书,查看证书指纹: 第二项工作:将证书与https绑定:以管理员身份启动cmd, ...

  5. IOS 内存斗争小史之 对象、指针、内存的基本理解

    1.指针和对象,都是内存块.一个大,一个小.一个在栈中,一个在堆中. 2.iOS中,我们可以生命一个指针,也可以通过alloc获取一块内存. 3.我们可以直接消灭掉一个指针,将其置为nil.但是我们没 ...

  6. JS --- reduce()函数

    定义: reduce() 方法接收一个函数作为累加器,数组中的每个值(从左到右)开始缩减,最终计算为一个值.对空数组是不会执行回调函数的. 案例 计算数组总和 var num = [1,2,3,4,5 ...

  7. java.lang.IllegalArgumentException: No converter found for return value of type: class XXX.XXXX

    最近项目中用到fastjson做接口数据的转换,发现报这个错误了,环境是springMVC4,看到阿里的官网说是“ 如果是使用 XML 的方式配置 Spring MVC 的话,只需在 Spring M ...

  8. 百度搜索推出惊雷算法严厉打击刷点击作弊行为-SEO公司分享

    百度搜索推出惊雷算法严厉打击刷点击作弊行为 2017年11月20日凌晨,百度搜索引擎发布更新惊雷算法旨在打击刷点击作弊行为. 下面是惊雷算法相关新闻报道: 百度搜索将于11月底推出惊雷算法,严厉打击通 ...

  9. 绝望的主妇第八季/Desperate Housewives迅雷下载

    绝望的主妇 第七季 Desperate Housewives Season 8(2011) 本季看点:曾经在<主妇>中有过重要演出的达娜·德拉尼(Dana Delany), 凯尔·麦克拉克 ...

  10. Matlab中使用LaTeX

    Matlab作为数据计算和处理的数学语言(软件),而LaTex作为出版界的重要排版语言(软件),尤其是对数学公式的排版功能特别强.在Matlab中有两种方法使用LaTeX:1)对Matlab生成的图形 ...