C#排序比较
与C#定义了相等性比较规范一样,C#也定义了排序比较规范,以确定一个对象与另一个对象的先后顺序。排序规范如下
- IComparable接口(包括IComparable接口和IComparable<T>接口)
- >和<运算符
当需要实现排序算法时,使用IComparable接口。在下面的例子中,Array.Sort静态方法可以调用,是因为System.String类实现了IComparable接口。
string[] colors={"Green", "Red", "Blue"};
Array.Sort(colors)
foreach(string c in colors)
Console.Write(c+ " ");
而<和>运算符比较特殊,因为他们一般用于比较数字类型。因为大于和小于运算符会被静态地解析,因此它们“产生”出高效的代码,适用于复杂计算的场景。
.NET Framework还提供了插件式的排序协议--IComparer接口。IComparable接口与IComparer接口的差别类似与IEquatable和IEqualityComparer接口 (关于IEqutable接口和IEqualityComparer接口,请参考C#相等性:http://www.cnblogs.com/yang_sy/p/3582946.html)
1. IComparable接口
IComparable接口的定义如下
public interface IComparable int CompareTo(Object obj);
} public interface IComparable<in T>
{
int CompareTo(T other);
}
这两个接口定义了相同的功能。对于值类型,IComparable<T>接口效率高于ICompare接口。上面的两个接口的CompareTo方法都按照下面的方式运行:
- 如果a排在b后面,那么a.CompareTo(b)返回1
- 如果a和不一样,那么返回0
- 如果a排在不前面,那么返回-1
我们来看下面的示例代码:
IList<Staff> staffs = new List<Staff>
{
new Staff{FirstName="AAA", Title="Manager", Dept="Sale"},
new Staff{FirstName="BBB", Title="Accountant", Dept="Finance"},
new Staff{FirstName="CCC", Title="Accountant", Dept="Finance"},
}; Console.WriteLine("BBB".CompareTo(staffs[0].FirstName)); // 1
Console.WriteLine("BBB".CompareTo(staffs[1].FirstName)); // 0
Console.WriteLine("BBB".CompareTo(staffs[2].FirstName)); // -1
C#的大部分基本类型都实现了IComparable接口和IComparable<T>接口。很多自定义类型同样也实现了该接口,这样便于排序。
IComarable与Equals
假设一个类型重写了Equals方法并实现了IComparable接口。那么你肯定希望当Equals返回true时,CompareTo应当返回0。而Equals返回false时,CompareTo可以返回任何值。
换句话说,相等性比对比性更严格;反之则不会。因此,当CompareTo说“两个对象相等”时,Equals会说“这两个对象不一定相等”。一个很好的例子来自System.String类。String.Equals方法和==运算符使用序号排序规则比较字符串--也就是通过每个字符的Unicode的值进行排序。而String.CompareTo方法,却使用不那么严格的基于文化区域(culture-dependent)进行比较。对于大多数计算机,字符ǖ和ṻ,Equals返回False,而CompareTo返回0
你可以实现通过IComparer接口,从而完成特定的排序算法。自定义IComparer接口的实现,进一步加大了CompareTo和Equals方法之间的差异。比如不区分大小写的字符串比较器,对于A和a,将返回0. 这也从反面印证了,ComparTo方法不如Equals方法严格。
2. <和>运算符
一些类型,定义了<和>运算符,比如:
bool after2010 = DateTime.Now > new DateTime(2010, 1, 1);
Console.WriteLine(after2010);
当实现<和>运算符之后,你需要保证<和>运算符与IComparable接口保持一致。这也是.NET Framework的标准。
同样地,当一个类型重载了<和>运算符,那么也要求实现IComparable接口,而反之则不需要。实际上,大多数.NET类型实现了IComparable接口,并没有重载<和>运算符。这(排序比较)与相等性比较不一样:
- 在实现相等性比较时,如果重载了Equals方法,那么一般都重载==运算符
- 而在实现排序性比较时,如果实现了CompareTo方法,一般不要求重载<运算符和>运算符
一般地,只有在下面的情形中,才需要重载<运算符和>运算符:
- 一个类型本身包含大于和小于这样的概念
- 执行先后顺序比较的方式是唯一的
- 结果不会随文化区域(Cultures)变化而变化
System.Stirng类型不满足最后一条,因此string不支持>操作和<操作。因此 “beck” > “Anne”,编译时会抛出错误。
3. 实现IComparable接口
下面的实例代码中,结构Note表示一个音乐的注释,它实现了IComparable接口,还重载了<运算符和>运算符。为了实例的完整性,我们还重写了Equals和GetHashCode方法,以及重载了==和!=运算符,通过这个例子,你可以全面的了解排序比较。
internal struct Note : IComparable, IComparable<Note>, IEquatable<Note>
{ private int semitonesFromA;
public int SemitonesFromA
{
get { return semitonesFromA; }
} public Note(int semitonesFromA)
{
this.semitonesFromA = semitonesFromA;
} // generic IComparable<T>
public int CompareTo(Note other)
{
if (Equals(other))
return 0;
return SemitonesFromA.CompareTo(other.SemitonesFromA);
} // non-generic IComaparable
public int IComparable.CompareTo(object other)
{
if (!(other is Note))
throw new InvalidOperationException("CompareTo: Not a note");
return CompareTo((Note)other);
} public static bool operator <(Note n1, Note n2)
{
return n1.CompareTo(n2) < 0;
} public static bool operator >(Note n1, Note n2)
{
return n1.CompareTo(n2) > 0;
} // for IEquatable
public bool Equals(Note other)
{
return this.SemitonesFromA == other.SemitonesFromA;
} // override Object.Equals
public override bool Equals(object other)
{
if (!(other is Note))
throw new InvalidOperationException("CompareTo: Not a note");
return Equals((Note)other);
} public override int GetHashCode()
{
return SemitonesFromA.GetHashCode();
} public static bool operator ==(Note n1, Note n2)
{
return n1.Equals(n2);
} public static bool operator !=(Note n1, Note n2)
{
return !(n1 == n2);
}
}
C#排序比较的更多相关文章
- javascript中的Array对象 —— 数组的合并、转换、迭代、排序、堆栈
Array 是javascript中经常用到的数据类型.javascript 的数组其他语言中数组的最大的区别是其每个数组项都可以保存任何类型的数据.本文主要讨论javascript中数组的声明.转换 ...
- iOS可视化动态绘制八种排序过程
前面几篇博客都是关于排序的,在之前陆陆续续发布的博客中,我们先后介绍了冒泡排序.选择排序.插入排序.希尔排序.堆排序.归并排序以及快速排序.俗话说的好,做事儿要善始善终,本篇博客就算是对之前那几篇博客 ...
- JavaScript实现常用的排序算法
▓▓▓▓▓▓ 大致介绍 由于最近要考试复习,所以学习js的时间少了 -_-||,考试完还会继续的努力学习,这次用原生的JavaScript实现以前学习的常用的排序算法,有冒泡排序.快速排序.直接插入排 ...
- [C#][算法] 用菜鸟的思维学习算法 -- 马桶排序、冒泡排序和快速排序
用菜鸟的思维学习算法 -- 马桶排序.冒泡排序和快速排序 [博主]反骨仔 [来源]http://www.cnblogs.com/liqingwen/p/4994261.html 目录 马桶排序(令人 ...
- 算法与数据结构(十三) 冒泡排序、插入排序、希尔排序、选择排序(Swift3.0版)
本篇博客中的代码实现依然采用Swift3.0来实现.在前几篇博客连续的介绍了关于查找的相关内容, 大约包括线性数据结构的顺序查找.折半查找.插值查找.Fibonacci查找,还包括数结构的二叉排序树以 ...
- 算法与数据结构(七) AOV网的拓扑排序
今天博客的内容依然与图有关,今天博客的主题是关于拓扑排序的.拓扑排序是基于AOV网的,关于AOV网的概念,我想引用下方这句话来介绍: AOV网:在现代化管理中,人们常用有向图来描述和分析一项工程的计划 ...
- 使用po模式读取豆瓣读书最受关注的书籍,取出标题、评分、评论、题材 按评分从小到大排序并输出到txt文件中
#coding=utf-8from time import sleepimport unittestfrom selenium import webdriverfrom selenium.webdri ...
- javascript排序
利用array中的sort()排序 w3cfunction sortNumber(a,b) { return a - b } var arr = new Array(6) arr[0] = " ...
- iOS自定义model排序
在开发过程中,可能需要按照model的某种属性排序. 1.自定义model @interface Person : NSObject @property (nonatomic,copy) NSStri ...
- Lucene4.4.0 开发之排序
排序是对于全文检索来言是一个必不可少的功能,在实际运用中,排序功能能在某些时候给我们带来很大的方便,比如在淘宝,京东等一些电商网站我们可能通过排序来快速找到价格最便宜的商品,或者通过排序来找到评论数最 ...
随机推荐
- Windows,linux快捷键
Window系统 按着Alt + 鼠标左键点击 = 直接打开点击空间的属性
- bzoj 1977
题意:求严格的次小生成树.点n<=100000,m<=300000 思路:很容易想到先做一边最小生成树,然后枚举每条非树边(u, v, w),然后其实就是把u,v路径上小于w的最大边替换成 ...
- [Phalcon-framework] Phalcon framework - Dependency Injection/Service Location And the MVC architecture note 1
Registering services in the Container - We can easily replace a component with one created by oursel ...
- 升级adt插件后,eclipse突然出现Unable to build: the file dx.jar was not loaded from the SDK folder 错误
旧版的SDK管理器里面最高只能安装Android 3.2 API,需要更新SDK管理器版本后才能安装Android 4.0.Android 4.1,方法如下: http://blog.csdn.net ...
- Dynamic CRM 2013学习笔记(六)备份和恢复
这节我们将讨论下怎么维护CRM,包括以下主要内容: 备份CRM DB 备份CRM 系统 恢复CRM DB 恢复 CRM 系统 一. 备份CRM DB 下面的步骤将为CRM DB创建一个维护计划 ...
- 地址转换协议ARP
地址转换协议ARP 在以太网协议中规定,同一局域网中的一台主机要和另一台主机进行直接通信,必须要知道目标主机的MAC地址.而在TCP/IP协议中,网络层和传输层只关心目标主机的IP地址.这就导致在以太 ...
- 云时代基础设置自动化管理利器: Chef
云时代的到来势不可挡.尤其作为程序员,我们每天或多或少的直接或间接的使用者各种云服务.云平台有很多种,如云软件(SaaS, Software as a service).云平台(PaaS, Platf ...
- [BTS]The join order has been enforced because a local join hint is used.;Duplicate key was ignored.".
在一个客户的BizTalk Server 2013 R2环境中会报如下的ERROR,查找相关资料后,先试试停掉所有Trace. Log Name: ApplicationSource: ...
- GPU---并行计算利器
转载请引用:GPU---并行计算利器 源于阿里巴巴CCO<猿来如此>分享 1 GPU是什么 如图1所示,这台PC机与普通PC机不同的是这里插了7张显卡,左下角是显卡,在中间的就是GPU芯片 ...
- 减小Chrome的内存占用的参数
步骤: 1.右击chrome浏览器快捷方式 属性 目标 后面添加 --purge-memory-button 2. 按 shift+esc 查看进程