java icomparer_构建可比较的对象(IComparable)

IComparable接口

System.IComparable接口指定了一种允许一个对象可基于某些特定键值进行排序的行为。

namespaceSystem

{

[ComVisible(true)]public interfaceIComparable

{

int CompareTo(objectobj);

}

}

CompareTo()方法背后的逻辑是,根据某个特定数据字段比较传入的对象与当前实例。CompareTo()方法的返回值被用来判断这个类型小于、大于或是等于它所比较的对象。

任何小于0的数字:这个实例在指定对象之前

0:这个实例等于指定对象

任何大于0的数字:这个实例在指定对象之后

构建可比较对象

System.Array类定义了一个名为 Sort()的静态方法。在内置类型(int、short、string等)上调用这个方法的时候,可以以数字/字母顺序对数组中的项排序,因为这些内置数据类型实现了IComparable。

构建可排序的Car类型

namespaceComparableCar

{classCar : IComparable

{

public int CurrentSpeed { get; set; }public string PetName { get; set; }public int CarID { get; set; }

publicCar() { }public Car( string name, int currSp, intid )

{

CurrentSpeed=currSp;

PetName=name;

CarID=id;

}int IComparable.CompareTo(objectobj)

{

Car temp= obj asCar;if (temp != null)

{if (this.CarID >temp.CarID)return 1;if (this.CarID

return 0;

}else

throw new ArgumentException("Parameter is not a Car!");

}}}

由于C#int数据类型(只是CLR System.Int32的简写形式)实现了IComparable,我们就可以按如下所示的方法实现ICompareTo()方法:

int IComparable.CompareTo( objectobj )

{

Car temp= obj asCar;if (temp != null)return this.CarID.CompareTo(temp.CarID);else

throw new ArgumentException("Parameter is not a Car!");

}

Car类型已经知道如何将它自己和类似对象进行对比:

namespaceComparableCar

{classProgram

{static void Main( string[] args )

{

Console.WriteLine("***** Fun with Object Sorting *****\n");

Car[] myAutos = new Car[5];

myAutos[0] = new Car("Rusty", 80, 1);

myAutos[1] = new Car("Mary", 40, 234);

myAutos[2] = new Car("Viper", 40, 34);

myAutos[3] = new Car("Mel", 40, 4);

myAutos[4] = new Car("Chucky", 40, 5);

Console.WriteLine("Here is the unordered set of cars:");foreach (Car c inmyAutos)

Console.WriteLine("{0} {1}", c.CarID, c.PetName);

Array.Sort(myAutos);

Console.WriteLine();

Console.WriteLine("Here is the ordered set of cars:");foreach (Car c inmyAutos)

Console.WriteLine("{0} {1}", c.CarID, c.PetName);Console.ReadLine();

}

}

}

be01d421e03fe31b7455bf4ad11ec455.png

指定多个排序顺序IComparer

如果要构建一个既可通过ID排序又可通过昵称排序的Car类型,就需要与另一个标准接口IComparer打交道。

namespaceSystem.Collections

{

[ComVisible(true)]public interfaceIComparer

{

int Compare(object x, objecty);

}

}

与IComparable接口不同,IComparer接口不是在要排序的类型(即Car)中,而是在许多辅助类中实现的,其中每个排序各有一个依据(如昵称、ID号等)。

namespaceComparableCar

{//这个辅助类用来通过昵称排序Car类型的数组

public classPetNameComparer : IComparer

{//测试每个对象的昵称

int IComparer.Compare( object o1, objecto2 )

{

Car t1= o1 asCar;

Car t2= o2 asCar;if (t1 != null && t2 != null)returnString.Compare(t1.PetName, t2.PetName);else

throw new ArgumentException("Parameter is not a Car!");

}

}

}

System.Array有许多重载的Sort()方法,其中有一个用来在对象上实现IComparer接口。

namespaceComparableCar

{classProgram

{static void Main( string[] args )

{

...

//按照昵称进行排序

Array.Sort(myAutos, newPetNameComparer());Console.WriteLine("Ordering by pet name:");foreach (Car c inmyAutos)

Console.WriteLine("{0} {1}", c.CarID, c.PetName);

...

}

}

}

自定义属性、自定义排序类型

值得指出的是,在通过特定数据字段排序Car类型的时候,可以使用自定义的静态属性辅助对象用户。假定Car类型添加了一个静态只读属性SortByPetName,它返回一个实现了IComparer接口的对象的实例(在本例中为PetNameComparer):

namespaceComparableCar

{

// 现在可以使用一个自定义静态属性来返回正确的IComparer接口classCar : IComparable

{...//返回SortByPetName比较的属性

public staticIComparer SortByPetName

{get { return (IComparer)newPetNameComparer(); } }

...}}

现在可以使用强关联属性按照昵称排序,而不是只能使用独立的PetNameComparer类型:

//简洁明了的按照昵称排序

Array.Sort(myAutos, Car.SortByPetName);

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值